{"id":18806722,"url":"https://github.com/lefred/myundelete","last_synced_at":"2025-04-13T19:12:57.037Z","repository":{"id":23471696,"uuid":"26836217","full_name":"lefred/MyUndelete","owner":"lefred","description":"Undelete deleted rows from MySQL ROW binary logs","archived":false,"fork":false,"pushed_at":"2018-01-05T23:57:55.000Z","size":29,"stargazers_count":29,"open_issues_count":3,"forks_count":14,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-03-27T09:52:00.791Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lefred.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-19T00:04:24.000Z","updated_at":"2025-02-14T06:18:20.000Z","dependencies_parsed_at":"2022-08-22T00:31:02.829Z","dependency_job_id":null,"html_url":"https://github.com/lefred/MyUndelete","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefred%2FMyUndelete","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefred%2FMyUndelete/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefred%2FMyUndelete/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lefred%2FMyUndelete/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lefred","download_url":"https://codeload.github.com/lefred/MyUndelete/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248766745,"owners_count":21158301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T22:49:24.138Z","updated_at":"2025-04-13T19:12:57.011Z","avatar_url":"https://github.com/lefred.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Stories in Ready](https://badge.waffle.io/lefred/MyUndelete.png?label=ready\u0026title=Ready)](https://waffle.io/lefred/MyUndelete)\n# MyUndelete\n\n\nUndelete deleted rows, delete inserted rows, revert updates from MySQL ROW binary logs.\n\nThis is still alpha, certainly the un-update part that has been tested with only v2 ROW events.\n\n## History\n\n\nAfter the nice blog post of Scott Noyes (http://thenoyes.com/littlenoise/?p=307), I decided to dig a bit more on the topic of undelete rows from the binary log.\n\nThis script allows to undelete records from the BINARY LOG in ROW FORMAT but also revert INSERTs and UPDATEs.\n\n## Syntax\n\n```\nMyUndelete.py -b \u003cbinlog\u003e -s \u003cstart position\u003e -e \u003cend position\u003e [-i] [-u]\n\n  -b | --binlog=  : path of the binary log file\n  -s | --start=   : start position\n  -e | --end=     : stop position\n  -i | --insert   : consider also INSERT statements (by default, only DELETE)\n  -u | --update   : consider also UPDATE statements (by default, only DELETE)\n  -d | --debug    : add debug messages\n\nInfo: The program expects that you have read access to the binary log\nand you have all eventual MySQL credential in ~/.my.cnf\n```\n\n## Example\n\n### Un-delete\n\n```\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n|  4 | Héloïse    |\n|  5 | Suhi       |\n+----+------------+\n5 rows in set (0.00 sec)\n\nmysql\u003e delete from fred where id \u003e3;\nQuery OK, 2 rows affected (0.04 sec)\n\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n+----+------------+\n3 rows in set (0.00 sec)\n\nmysql\u003e show binlog events in 'mysql-bin.000008';\n+------------------+------+-------------+-----------+-------------+---------------------------------------+\n| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                  |\n+------------------+------+-------------+-----------+-------------+---------------------------------------+\n...\n| mysql-bin.000008 | 1514 | Query       |         1 |        1586 | BEGIN                                 |\n| mysql-bin.000008 | 1586 | Table_map   |         1 |        1636 | table_id: 72 (fred.fred)              |\n| mysql-bin.000008 | 1636 | Delete_rows |         1 |        1694 | table_id: 72 flags: STMT_END_F        |\n| mysql-bin.000008 | 1694 | Xid         |         1 |        1725 | COMMIT /* xid=146 */                  |\n+------------------+------+-------------+-----------+-------------+---------------------------------------+\n\n$ sudo ./MyUndelete.py  -b /var/lib/mysql/mysql-bin.000008 -s 1514 -e 1725\n\n*** WARNING *** USE WITH CARE ****\n\nBinlog file is  /var/lib/mysql/mysql-bin.000008\nStart Position file is  1514\nEnd Postision file is  1725\nEvent type (' ') is a delete v2\nReady to revert the statement ? [y/n]\ny\nDone... I hope it worked ;)\n\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n|  4 | Héloïse    |\n|  5 | Suhi       |\n+----+------------+\n5 rows in set (0.00 sec)\n\n```\n\n### Un-insert\n\n\nDelete an insert that happened in binary log mysqld-bin.000004 between positon 41989 and 42207.\n\n```\n$ sudo ./MyUndelete.py -s 41989 -e 42207 -i -b /var/lib/mysql/mysqld-bin.000004\n\n*** WARNING *** USE WITH CARE ****\n\nBinlog file is  /var/lib/mysql/mysqld-bin.000004\nStart Position file is  41989\nEnd Postision file is  42207\nWe also look to undo INSERTs\nEvent type ('\\x1e') is an insert v2\nReady to revert the statement ? [y/n]\ny\nDone... I hope it worked ;)\n```\n\n### Un-update\n\n\nLet's modify some records and then revert the changes:\n\n```\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n|  4 | Héloïse    |\n|  5 | Suhi       |\n+----+------------+\nmysql\u003e update fred set name = concat(name, \"2\") where id \u003e3;\nQuery OK, 2 rows affected (0.03 sec)\nRows matched: 2  Changed: 2  Warnings: 0\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n|  4 | Héloïse2   |\n|  5 | Suhi2      |\n+----+------------+\n5 rows in set (0.00 sec)\n\nmysql\u003e show master status;\n+------------------+----------+--------------+------------------+-------------------+\n| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |\n+------------------+----------+--------------+------------------+-------------------+\n| mysql-bin.000008 |      357 |              |                  |                   |\n+------------------+----------+--------------+------------------+-------------------+\nmysql\u003e show binlog events in 'mysql-bin.000008';\n+------------------+-----+-------------+-----------+-------------+---------------------------------------+\n| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                  |\n+------------------+-----+-------------+-----------+-------------+---------------------------------------+\n| mysql-bin.000008 |   4 | Format_desc |         1 |         120 | Server ver: 5.6.21-log, Binlog ver: 4 |\n| mysql-bin.000008 | 120 | Query       |         1 |         192 | BEGIN                                 |\n| mysql-bin.000008 | 192 | Table_map   |         1 |         242 | table_id: 72 (fred.fred)              |\n| mysql-bin.000008 | 242 | Update_rows |         1 |         326 | table_id: 72 flags: STMT_END_F        |\n| mysql-bin.000008 | 326 | Xid         |         1 |         357 | COMMIT /* xid=22 */                   |\n+------------------+-----+-------------+-----------+-------------+---------------------------------------+\n5 rows in set (0.00 sec)\n\n$ sudo ./MyUndelete.py  -b /var/lib/mysql/mysql-bin.000008 -s 120 -e 357 -u\n\n*** WARNING *** USE WITH CARE ****\n\nBinlog file is  /var/lib/mysql/mysql-bin.000008\nStart Position file is  120\nEnd Postision file is  357\nEvent type ('\\x1f') is an update v2\nWe got an update!!\nReady to revert the statement ? [y/n]\ny\nSending to mysql...\nDone... I hope it worked ;)\n\nmysql\u003e select * from fred;\n+----+------------+\n| id | name       |\n+----+------------+\n|  1 | Fred       |\n|  2 | Jen        |\n|  3 | Wilhelmine |\n|  4 | Héloïse    |\n|  5 | Suhi       |\n+----+------------+\n5 rows in set (0.00 sec)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flefred%2Fmyundelete","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flefred%2Fmyundelete","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flefred%2Fmyundelete/lists"}