Skip to content

Bits of .NET

Daily micro-tips for C#, SQL, performance, and scalable backend engineering.

  • Asp.Net Core
  • C#
  • SQL
  • JavaScript
  • CSS
  • About
  • ErcanOPAK.com
  • No Access
  • Privacy Policy
Wordpress

Recover Deleted WordPress Posts from Database (Even Without Backups)

- 01.02.26 | 01.02.26 - ErcanOPAK

Accidentally permanently deleted a post? If you acted within 30 days and your host hasn’t optimized the database, there’s a good chance it’s still recoverable.

How WordPress “Deletes” Posts:
When you empty trash, WordPress doesn’t immediately erase the post row. It updates the post_status to ‘trash’ first, then later to ‘inherit’ (for revisions). The actual deletion happens during database optimization or after 30 days.

Quick Check via phpMyAdmin:

SELECT * FROM wp_posts 
WHERE post_title LIKE '%keyword from your post%'
AND post_status IN ('trash', 'inherit', 'auto-draft')
ORDER BY post_modified DESC
LIMIT 20;

Replace ‘keyword from your post’ with something you remember from the title or content.

Recovery Steps:
If you found your post in the results:

UPDATE wp_posts 
SET post_status = 'draft'
WHERE ID = YOUR_POST_ID;

Your post is now in Drafts! Go to WordPress admin → Posts → Drafts to find it.

Advanced: Recover from Binary Logs (MySQL):
If your host enables binary logging, you can recover even truly deleted data:

mysqlbinlog /var/lib/mysql/mysql-bin.000001 | grep -A 50 "INSERT INTO wp_posts"

This shows all INSERT statements, including your deleted post’s original data. You’ll need server SSH access and MySQL permissions.

Why This Works:
Databases use “lazy deletion” for performance. Marking rows as deleted (via status flags) is faster than removing them entirely. The physical deletion happens during OPTIMIZE TABLE operations:

OPTIMIZE TABLE wp_posts;  # Don't run this if trying to recover!

Prevention for Future:
Install this mu-plugin (mu-plugins folder, auto-active):

<?php
// Prevent permanent deletion
add_action('wp_trash_post', function($post_id) {
    update_post_meta($post_id, '_deleted_date', current_time('mysql'));
});

This stamps every trashed post with deletion timestamp in post meta. Even if the post row disappears, postmeta often survives longer and helps locate backup points.

Related posts:

WordPress Pages Randomly Lose Formatting

WordPress: Create Custom Post Types for Portfolios, Products, Reviews

WordPress — wp_options Autoload Kills TTFB

Post Views: 8

Post navigation

Stop WordPress Comment Spam Without Plugins Using This .htaccess Rule
Debug Kubernetes Pods That Keep Crashing Before Logs Disappear

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

June 2026
M T W T F S S
1234567
891011121314
15161718192021
22232425262728
2930  
« May    

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (806)
  • How to enable, disable and check if Service Broker is enabled on a database in SQL Server (580)
  • Add Constraint to SQL Table to ensure email contains @ (580)
  • Average of all values in a column that are not zero in SQL (540)
  • How to use Map Mode for Vertical Scroll Mode in Visual Studio (506)
  • Find numbers with more than two decimal places in SQL (455)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files
  • Ajax: Add Custom Headers to Fetch Requests
  • JavaScript: Use console.table to Display Arrays as Tables
  • HTML: Use Spellcheck Attribute to Enable Browser Spell Check
  • CSS: Use user-select to Prevent Text Selection
  • Windows 11: Use Snipping Tool for Instant Screenshots

Most Viewed Posts

  • Get the User Name and Domain Name from an Email Address in SQL (953)
  • How to add default value for Entity Framework migrations for DateTime and Bool (882)
  • Get the First and Last Word from a String or Sentence in SQL (838)
  • How to select distinct rows in a datatable in C# (808)
  • How to make theater mode the default for Youtube (806)

Recent Posts

  • C#: Use String Interpolation Instead of Concatenation
  • C#: Use Tuples to Return Multiple Values from Methods
  • SQL: Use ISNULL and NULLIF for Smart NULL Handling
  • .NET Core: Use Data Annotations for Model Validation
  • Git: Use Git Clean to Remove Untracked Files

Social

  • ErcanOPAK.com
  • GoodReads
  • LetterBoxD
  • Linkedin
  • The Blog
  • Twitter
© 2026 Bits of .NET | Built with Xblog Plus free WordPress theme by wpthemespace.com