☰
WORDPRESS / PRACTICE

Як очистити orphaned postmeta у WordPress без ризику для даних

Як очистити orphaned postmeta у WordPress без ризику для даних

У таблиці wp_postmeta WordPress зберігає додаткові дані записів: значення полів, налаштування плагінів, параметри шаблонів та іншу пов’язану інформацію. Після видалення записів, невдалого імпорту або помилки плагіна частина цих рядків може залишитися без відповідного запису у wp_posts.

Такі рядки називають orphaned postmeta, або «сирітськими» метаданими. Вони не відновлюють видалені записи, але збільшують таблицю, ускладнюють резервне копіювання та можуть погіршувати обслуговування бази. Очищення потрібно виконувати після перевірки, а не запускати наосліп.

Що таке orphaned postmeta і чому вони з’являються

Кожен рядок у wp_postmeta має значення post_id, яке має відповідати ID запису в wp_posts. Якщо запис видалили, а пов’язані метадані залишилися, виникає orphaned postmeta — метадані без батьківського запису.

Найчастіші причини — масове видалення контенту, імпорт із помилками, некоректне видалення даних плагіном, міграція сайту або ручні операції в базі. Іноді «сироти» залишаються після видалення записів із кошика, якщо плагін або нестандартний скрипт не очистив пов’язані рядки.

Сам факт наявності таких рядків не означає, що сайт уже працює неправильно. Перед видаленням потрібно переконатися, що це справді метадані неіснуючих записів, а не результат помилки в префіксі таблиць чи неповної міграції.

  • Не плутайте orphaned postmeta з метаданими записів у кошику, чернеток або записів із нестандартним post type: вони все ще мають рядок у wp_posts.
  • Не видаляйте метадані лише тому, що певний meta_key здається непотрібним. Один і той самий ключ може використовуватися різними плагінами або типами записів.

Підготовка до перевірки та очищення

Усі команди нижче виконуються з каталогу WordPress через WP-CLI. Спочатку перевірте, який префікс таблиць використовує сайт. У прикладах застосовано wp_, але в реальному проєкті це може бути інше значення.

Перед DELETE створіть резервну копію бази. Найкраще зберегти її в окремий файл і переконатися, що файл створився та має ненульовий розмір. Для критичного сайту бажано також мати перевірений спосіб відновлення.

На час очищення не запускайте імпорт, масове редагування записів або процеси, які можуть одночасно змінювати wp_posts і wp_postmeta.

  • Перевірте підключення WP-CLI до потрібної інсталяції та бази даних.
  • Зафіксуйте префікс таблиць і не копіюйте запит без його перевірки.
  • Виконуйте операцію у вікно низького навантаження.
  • Збережіть результат перевірки кількості та приклади рядків до очищення.
wp db export before-orphaned-postmeta.sql

wp db query "SHOW TABLES;"

Як порахувати orphaned postmeta

Для пошуку використовуйте LEFT JOIN між wp_postmeta та wp_posts. Умова p.ID IS NULL залишає лише ті метадані, для яких не знайдено відповідний запис.

Цей запит нічого не видаляє, тому його можна виконати як первинну перевірку. Якщо результат дорівнює нулю, очищення не потрібне.

wp db query "
SELECT COUNT(*) AS orphaned_count
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
"

Перегляд прикладів і розподіл за meta_key

Однієї кількості недостатньо. Перегляньте конкретні рядки, щоб побачити post_id, ключ метаданих і частину значення. Великі або серіалізовані значення краще не виводити повністю: це може створити надмірний обсяг у терміналі.

wp db query "
SELECT pm.meta_id, pm.post_id, pm.meta_key,
       LEFT(pm.meta_value, 200) AS meta_value_preview
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL
ORDER BY pm.meta_id
LIMIT 50;
"

wp db query "
SELECT pm.meta_key, COUNT(*) AS rows_count
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL
GROUP BY pm.meta_key
ORDER BY rows_count DESC;
"

Як безпечно видалити сирітські метадані

Якщо перевірка підтвердила, що знайдені рядки справді не належать жодному запису, можна видалити їх за тим самим критерієм. Запит видаляє лише рядки з wp_postmeta, для яких у wp_posts немає відповідного ID.

Не змінюйте умову на ширший фільтр без чіткого розуміння наслідків. Зокрема, не варто видаляти всі рядки з певним meta_key або всі метадані старих записів лише за датою.

  • Перед виконанням ще раз перевірте префікс таблиць.
  • Переконайтеся, що резервна копія створена до запуску DELETE.
  • Після операції перевірте кількість orphaned postmeta повторним SELECT.
  • Якщо рядків дуже багато, спершу протестуйте операцію на копії бази або обговоріть пакетне видалення з адміністратором бази.
wp db query "
DELETE pm
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
"

Контроль після очищення

Після DELETE повторіть запит COUNT. У нормальній ситуації він має повернути нуль, якщо під час операції інший процес не створив нові проблемні рядки.

Також перевірте сайт у браузері: сторінки записів, адмінпанель, пошук, форми та функції, які залежать від плагінів. Особливо уважно протестуйте кастомні типи записів і поля, що зберігаються у postmeta.

Якщо таблиця залишилася великою, це не обов’язково означає, що очищення не спрацювало. DELETE прибирає рядки, але фізичний розмір таблиці на диску може не зменшитися одразу. Оптимізацію таблиці слід виконувати окремо, після резервного копіювання та з урахуванням блокувань і навантаження.

wp db query "
SELECT COUNT(*) AS orphaned_count
FROM wp_postmeta pm
LEFT JOIN wp_posts p ON p.ID = pm.post_id
WHERE p.ID IS NULL;
"

Особливості multisite та нестандартних баз

У WordPress Multisite кожен сайт має власні таблиці записів і метаданих, наприклад wp_2_posts та wp_2_postmeta. Перевіряти й очищати їх потрібно окремо. Не можна автоматично вважати, що таблиці першого сайту містять дані всіх сайтів мережі.

Для кожної пари таблиць підставте правильний префікс. Перед масовою обробкою всіх сайтів спочатку протестуйте запит на одному сайті та переконайтеся, що він не зачіпає мережеві таблиці або дані іншої інсталяції.

Якщо сайт використовує нестандартну структуру, кілька баз або зовнішню систему імпорту, з’ясуйте джерело даних. Плагін може повторно створити orphaned postmeta після наступної синхронізації.

  • Перевіряйте кожен префікс окремо.
  • Не запускайте запит із wp_ на всій мережі, якщо не підтверджено, що це потрібний сайт.
  • Після очищення перевірте журнали імпорту та завдання cron, які могли залишити проблему.

Поширені помилки під час очищення

Найнебезпечніша помилка — виконати DELETE без попереднього SELECT і резервної копії. Навіть коректний на вигляд запит може бути запущений не в тій базі або з неправильним префіксом.

Інша проблема — спроба виправити розмір бази видаленням усіх «старих» або «невідомих» meta_key. Це може зламати функціональність плагіна, шаблону чи кастомного типу запису.

Не слід вважати оптимізацію таблиці заміною очищення. Спочатку потрібно визначити й видалити лише некоректні рядки, а вже потім оцінювати потребу в оптимізації. Якщо orphaned-метадані з’являються знову, шукайте плагін або процес, який їх створює.

  • Не використовуйте запит без перевірки назви бази та таблиць.
  • Не видаляйте рядки лише за meta_key.
  • Не ігноруйте повторну появу проблеми після очищення.
  • Не проводьте операцію на робочому сайті без актуальної резервної копії.

Поширені запитання

Чи безпечно видаляти всі orphaned postmeta?

Якщо перевірка виконана коректно, а рядки справді не мають відповідного запису у wp_posts, їх можна видалити. Перед операцією обов’язково зробіть резервну копію та перевірте приклади рядків.

Чи видалить цей запит самі записи WordPress?

Ні. Запит видаляє лише рядки з wp_postmeta, для яких не знайдено ID у wp_posts. Записи, чернетки, сторінки та записи в кошику він не зачіпає.

Чому після очищення розмір wp_postmeta не зменшився?

Видалення рядків і зменшення фізичного розміру таблиці — різні операції. СУБД може залишити звільнений простір для повторного використання. Оптимізацію таблиці розглядайте окремо після резервного копіювання.

Як очищати orphaned postmeta у Multisite?

Окремо для кожної пари таблиць конкретного сайту, наприклад wp_2_posts і wp_2_postmeta. Спочатку перевірте префікси та запустіть SELECT, щоб не переплутати сайти.

Висновок

Очищення orphaned postmeta — це точкова операція, а не механічне видалення зайвих метаданих. Безпечний порядок дій такий: визначити правильні таблиці, створити резервну копію, порахувати рядки, переглянути приклади, виконати DELETE за умовою відсутності запису у wp_posts і перевірити результат.

Якщо «сироти» регулярно з’являються знову, проблема, ймовірно, пов’язана з імпортом, плагіном або власним кодом. У такому разі важливо усунути джерело, а не повторювати очищення вручну.

← Усі матеріали WordPress