MySQLの復旧をお願いします!!

解いた人:Hunachi

参照した問題・解説のサイト:MySQLの復旧をお願いします!!

使用環境・ツール

環境

  • IPアドレス: 192.168.0.1
  • ユーザー: admin
  • パスワード: USerPw@19
  • DBユーザー: root
  • DBパスワード: root

状況

  • このMySQLは毎日定時にsysbench databaseのバックアップを取得していて(コンテスト問題の作成上truncate table文が実行された日まで)、偶然truncate文が実行される(数分)前にこの日のバックアップが完了していた
  • バックアップは以下のコマンドで取得されている
  • mysqldump --opt --single-transaction --master-data=2 --default-character-set=utf8mb4 --databases sysbench > /root/backup/backup.dump
  • mysql -u root -p < /root/backup/backup.dumpでバックアップが取得された時点に復旧できる
  • adminユーザからsudo suすることでrootユーザから操作してください

問題

問1

truncate table sbtest3;というクエリが実行された日時をyymmdd HH:MM:SSのフォーマットで報告してください。 また、どのようにこの日時を特定したかを説明してください。

問2

truncate tableが実行される直前の状態(truncate tableが実行される1つ前のクエリが実行された状態)にデータを復旧し、復旧後checksum table sysbench.sbtest3;の結果を報告してください。 また、データの復旧に必要な手順を説明してください。


技術調査

問1について

  • 実行されたmysqlコマンドの履歴を表示する方法 cat ~/.mysql_history で実行されたmysqlコマンドの履歴を表示することができるはず。参考

これで試した結果(dockerで環境作ってクエリを適当に打った)

# cat ~/.mysql_history
_HiStOrY_V2_
show\040databases;
quit;

\040はASCIIコードのスペースだけど、見づらいのでこれはスペースで表示させるようにする。

# sed "s/\\\040/ /g"  ~/.mysql_history
_HiStOrY_V2_
show databases;
quit;

sedコマンドについて参考になるサイト

日時が表示されてないのでだめ!

どうやらデフォで日時を取得する方法ないかも。。?   https://forums.mysql.com/read.php?10,400933 https://forums.mysql.com/read.php?10,400933,401057#msg-401057

そこで、 general_logが有効になっているかを確認する。 show variables like 'general_log'; もし、

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| general_log   | ON    |
+---------------+-------+
1 row in set (0.00 sec)

ならラッキー、いける。 OFFなら自分にはお手上げ😭🙌

ONだったら、 show variables like 'general_log_file'; でわかるファイルをみてみる。

実験した

  1. デフォではOFFだったので、 mysql> set global general_log = 'ON';を設定。
  2. 色々コマンドを打つ。
  3. cat /var/lib/mysql/${general_log_file's value}.log
  4. 表示される例。
/usr/sbin/mysqld, Version: 8.0.25 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2021-08-16T08:48:21.048791Z	   15 Query	SELECT DATABASE()
2021-08-16T08:48:21.049349Z	   15 Init DB	hunadb
2021-08-16T08:48:21.052633Z	   15 Query	show databases
2021-08-16T08:48:21.053892Z	   15 Query	show tables
2021-08-16T08:48:21.055342Z	   15 Field List	piyo 
2021-08-16T08:48:32.444434Z	   15 Quit	
2021-08-16T08:48:34.020718Z	   16 Connect	root@localhost on  using Socket
2021-08-16T08:48:34.021351Z	   16 Query	select @@version_comment limit 1
2021-08-16T08:48:36.401359Z	   16 Query	show variables like 'general_log'
2021-08-16T08:48:46.839490Z	   16 Query	create table hunadb.piyo (id int, cost int)
2021-08-16T08:49:06.218438Z	   16 Query	create table hunadb.hiyo (id int, cost int)
2021-08-16T08:49:43.064247Z	   16 Query	truncate table hunadb.piyo
2021-08-16T08:49:48.068001Z	   16 Quit

↑の日時を解答として提出すれば良さそう!!

問2について

状況にて、バックアップの復旧方法を教えてくれてるのでそれをする。(括弧内は自分が打ったコマンド。ログも実際も私の物。)

  1. mysqldump --opt --single-transaction --master-data=2 --default-character-set=utf8mb4 --databases sysbench > /root/backup/backup.dump (を打つべきだけどこの時は手を抜いてmysqldump hunadb > dump.sql)
  2. mysql -u root -p < /root/backup/backup.dump(実際に打ったのは、mysql hunadb < dump.sql)
  3. .mysql_historyを確認してみる。
/usr/sbin/mysqld, Version: 8.0.25 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
2021-08-16T08:48:21.048791Z	   15 Query	SELECT DATABASE()
2021-08-16T08:48:21.049349Z	   15 Init DB	hunadb
2021-08-16T08:48:21.052633Z	   15 Query	show databases
2021-08-16T08:48:21.053892Z	   15 Query	show tables
2021-08-16T08:48:21.055342Z	   15 Field List	piyo 
2021-08-16T08:48:32.444434Z	   15 Quit	
2021-08-16T08:48:34.020718Z	   16 Connect	root@localhost on  using Socket
2021-08-16T08:48:34.021351Z	   16 Query	select @@version_comment limit 1
2021-08-16T08:48:36.401359Z	   16 Query	show variables like 'general_log'
2021-08-16T08:48:46.839490Z	   16 Query	create table hunadb.piyo (id int, cost int)
2021-08-16T08:49:06.218438Z	   16 Query	create table hunadb.hiyo (id int, cost int)
2021-08-16T08:49:43.064247Z	   16 Query	truncate table hunadb.piyo
2021-08-16T08:49:48.068001Z	   16 Quit	
2021-08-16T09:43:42.989880Z	   17 Connect	root@localhost on  using Socket
2021-08-16T09:43:42.990214Z	   17 Query	select @@version_comment limit 1
2021-08-16T10:08:24.906898Z	   17 Query	SELECT * FROM msdb.dbo
2021-08-16T10:08:34.540831Z	   17 Query	show databases
2021-08-16T10:10:22.024284Z	   17 Quit	

--- ここでバックアップを取った --- ( mysqldump hunadb > dump.sql ) 

2021-08-16T10:10:31.893768Z	   18 Connect	root@localhost on  using Socket
2021-08-16T10:10:31.893799Z	   18 Connect	Access denied for user 'root'@'localhost' (using password: NO)
2021-08-16T10:11:05.935347Z	   19 Connect	root@localhost on  using Socket
2021-08-16T10:11:05.935406Z	   19 Connect	Access denied for user 'root'@'localhost' (using password: NO)
2021-08-16T10:11:29.099579Z	   20 Connect	root@localhost on  using Socket
2021-08-16T10:11:29.099723Z	   20 Query	/*!40100 SET @@SQL_MODE='' */
2021-08-16T10:11:29.099984Z	   20 Query	/*!40103 SET TIME_ZONE='+00:00' */
2021-08-16T10:11:29.100167Z	   20 Query	/*!80000 SET SESSION information_schema_stats_expiry=0 */
2021-08-16T10:11:29.100304Z	   20 Query	SET SESSION NET_READ_TIMEOUT= 86400, SESSION NET_WRITE_TIMEOUT= 86400
2021-08-16T10:11:29.101544Z	   20 Query	SHOW VARIABLES LIKE 'gtid\_mode'
2021-08-16T10:11:29.103106Z	   20 Query	SELECT LOGFILE_GROUP_NAME, FILE_NAME, TOTAL_EXTENTS, INITIAL_SIZE, ENGINE, EXTRA FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'UNDO LOG' AND FILE_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IS NOT NULL AND LOGFILE_GROUP_NAME IN (SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('hunadb'))) GROUP BY LOGFILE_GROUP_NAME, FILE_NAME, ENGINE, TOTAL_EXTENTS, INITIAL_SIZE ORDER BY LOGFILE_GROUP_NAME
2021-08-16T10:11:29.110332Z	   20 Query	SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME, EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE' AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_SCHEMA IN ('hunadb')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME
2021-08-16T10:11:29.112213Z	   20 Query	SHOW VARIABLES LIKE 'ndbinfo\_version'
2021-08-16T10:11:29.114053Z	   20 Init DB	hunadb
2021-08-16T10:11:29.114225Z	   20 Query	show tables
2021-08-16T10:11:29.115254Z	   20 Query	LOCK TABLES `hiyo` READ /*!32311 LOCAL */,`piyo` READ /*!32311 LOCAL */
2021-08-16T10:11:29.116322Z	   20 Query	show table status like 'hiyo'
2021-08-16T10:11:29.117349Z	   20 Query	SET SQL_QUOTE_SHOW_CREATE=1
2021-08-16T10:11:29.117507Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.117621Z	   20 Query	show create table `hiyo`
2021-08-16T10:11:29.117877Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.118037Z	   20 Query	show fields from `hiyo`
2021-08-16T10:11:29.119264Z	   20 Query	show fields from `hiyo`
2021-08-16T10:11:29.120115Z	   20 Query	SELECT /*!40001 SQL_NO_CACHE */ * FROM `hiyo`
2021-08-16T10:11:29.120363Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.120561Z	   20 Query	use `hunadb`
2021-08-16T10:11:29.120795Z	   20 Query	select @@collation_database
2021-08-16T10:11:29.121025Z	   20 Query	SHOW TRIGGERS LIKE 'hiyo'
2021-08-16T10:11:29.122437Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.122713Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.122975Z	   20 Query	SELECT COLUMN_NAME,                       JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"')                FROM information_schema.COLUMN_STATISTICS                WHERE SCHEMA_NAME = 'hunadb' AND TABLE_NAME = 'hiyo'
2021-08-16T10:11:29.123610Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.123849Z	   20 Query	show table status like 'piyo'
2021-08-16T10:11:29.124940Z	   20 Query	SET SQL_QUOTE_SHOW_CREATE=1
2021-08-16T10:11:29.125141Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.125352Z	   20 Query	show create table `piyo`
2021-08-16T10:11:29.125741Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.125958Z	   20 Query	show fields from `piyo`
2021-08-16T10:11:29.127051Z	   20 Query	show fields from `piyo`
2021-08-16T10:11:29.128547Z	   20 Query	SELECT /*!40001 SQL_NO_CACHE */ * FROM `piyo`
2021-08-16T10:11:29.128818Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.128976Z	   20 Query	use `hunadb`
2021-08-16T10:11:29.129195Z	   20 Query	select @@collation_database
2021-08-16T10:11:29.129379Z	   20 Query	SHOW TRIGGERS LIKE 'piyo'
2021-08-16T10:11:29.130227Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.130402Z	   20 Query	SET SESSION character_set_results = 'binary'
2021-08-16T10:11:29.130667Z	   20 Query	SELECT COLUMN_NAME,                       JSON_EXTRACT(HISTOGRAM, '$."number-of-buckets-specified"')                FROM information_schema.COLUMN_STATISTICS                WHERE SCHEMA_NAME = 'hunadb' AND TABLE_NAME = 'piyo'
2021-08-16T10:11:29.131010Z	   20 Query	SET SESSION character_set_results = 'utf8mb4'
2021-08-16T10:11:29.131201Z	   20 Query	UNLOCK TABLES
2021-08-16T10:11:29.132686Z	   20 Quit	

---- 多分ここまでがバックアップのためのコード ----

2021-08-16T10:12:17.133740Z	   22 Connect	root@localhost on  using Socket
2021-08-16T10:12:17.134045Z	   22 Query	select @@version_comment limit 1
2021-08-16T10:12:27.437396Z	   22 Query	SELECT DATABASE()
2021-08-16T10:12:27.437700Z	   22 Init DB	hunadb
2021-08-16T10:12:27.438758Z	   22 Query	show databases
2021-08-16T10:12:27.439753Z	   22 Query	show tables
2021-08-16T10:12:27.440834Z	   22 Field List	hiyo 
2021-08-16T10:12:27.442166Z	   22 Field List	piyo 
2021-08-16T10:12:31.924121Z	   22 Query	show tables
2021-08-16T10:12:40.044363Z	   22 Query	truncate table hiyo
2021-08-16T10:12:42.415083Z	   22 Query	show tables
2021-08-16T10:13:24.213758Z	   22 Query	drop table hiyo
2021-08-16T10:13:26.758317Z	   22 Query	show tables
2021-08-16T10:13:30.474725Z	   22 Quit	

---- ここで復元を始めた ---- ( mysql hunadb < dump.sql )

2021-08-16T10:13:58.825694Z	   23 Connect	root@localhost on hunadb using Socket
2021-08-16T10:13:58.826015Z	   23 Query	select @@version_comment limit 1
2021-08-16T10:13:58.826260Z	   23 Query	/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */
2021-08-16T10:13:58.826450Z	   23 Query	/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */
2021-08-16T10:13:58.826626Z	   23 Query	/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */
2021-08-16T10:13:58.826805Z	   23 Query	/*!50503 SET NAMES utf8mb4 */
2021-08-16T10:13:58.827039Z	   23 Query	/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */
2021-08-16T10:13:58.827220Z	   23 Query	/*!40103 SET TIME_ZONE='+00:00' */
2021-08-16T10:13:58.827404Z	   23 Query	/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */
2021-08-16T10:13:58.827586Z	   23 Query	/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */
2021-08-16T10:13:58.827784Z	   23 Query	/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */
2021-08-16T10:13:58.827967Z	   23 Query	/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */
2021-08-16T10:13:58.828183Z	   23 Query	DROP TABLE IF EXISTS `hiyo`
2021-08-16T10:13:58.832544Z	   23 Query	/*!40101 SET @saved_cs_client     = @@character_set_client */
2021-08-16T10:13:58.832736Z	   23 Query	/*!50503 SET character_set_client = utf8mb4 */
2021-08-16T10:13:58.832935Z	   23 Query	CREATE TABLE `hiyo` (
  `id` int DEFAULT NULL,
  `cost` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
2021-08-16T10:13:58.846132Z	   23 Query	/*!40101 SET character_set_client = @saved_cs_client */
2021-08-16T10:13:58.846305Z	   23 Query	LOCK TABLES `hiyo` WRITE
2021-08-16T10:13:58.847102Z	   23 Query	/*!40000 ALTER TABLE `hiyo` DISABLE KEYS */
2021-08-16T10:13:58.848155Z	   23 Query	/*!40000 ALTER TABLE `hiyo` ENABLE KEYS */
2021-08-16T10:13:58.849204Z	   23 Query	UNLOCK TABLES
2021-08-16T10:13:58.849372Z	   23 Query	DROP TABLE IF EXISTS `piyo`
2021-08-16T10:13:58.857241Z	   23 Query	/*!40101 SET @saved_cs_client     = @@character_set_client */
2021-08-16T10:13:58.857442Z	   23 Query	/*!50503 SET character_set_client = utf8mb4 */
2021-08-16T10:13:58.857621Z	   23 Query	CREATE TABLE `piyo` (
  `id` int DEFAULT NULL,
  `cost` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
2021-08-16T10:13:58.869241Z	   23 Query	/*!40101 SET character_set_client = @saved_cs_client */
2021-08-16T10:13:58.869410Z	   23 Query	LOCK TABLES `piyo` WRITE
2021-08-16T10:13:58.870143Z	   23 Query	/*!40000 ALTER TABLE `piyo` DISABLE KEYS */
2021-08-16T10:13:58.871175Z	   23 Query	/*!40000 ALTER TABLE `piyo` ENABLE KEYS */
2021-08-16T10:13:58.872237Z	   23 Query	UNLOCK TABLES
2021-08-16T10:13:58.872430Z	   23 Query	/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */
2021-08-16T10:13:58.872583Z	   23 Query	/*!40101 SET SQL_MODE=@OLD_SQL_MODE */
2021-08-16T10:13:58.872726Z	   23 Query	/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */
2021-08-16T10:13:58.872864Z	   23 Query	/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */
2021-08-16T10:13:58.873030Z	   23 Query	/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */
2021-08-16T10:13:58.873174Z	   23 Query	/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */
2021-08-16T10:13:58.873287Z	   23 Query	/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */
2021-08-16T10:13:58.873427Z	   23 Query	/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */
2021-08-16T10:13:58.873506Z	   23 Quit	

---- ここまでが復元された時のログ ----

2021-08-16T10:14:05.000746Z	   24 Connect	root@localhost on  using Socket
2021-08-16T10:14:05.001258Z	   24 Query	select @@version_comment limit 1
2021-08-16T10:14:12.021449Z	   24 Query	SELECT DATABASE()
2021-08-16T10:14:12.021944Z	   24 Init DB	hunadb
2021-08-16T10:14:12.023879Z	   24 Query	show databases
2021-08-16T10:14:12.025276Z	   24 Query	show tables
2021-08-16T10:14:12.026755Z	   24 Field List	hiyo 
2021-08-16T10:14:12.027480Z	   24 Field List	piyo 
2021-08-16T10:14:13.866961Z	   24 Query	show tables
2021-08-16T10:14:16.344213Z	   24 Quit	

ログの見方がよくわからないけど、これのバックアップが始まってそうな部分を見つけて、それ以外の部分のlogに書いてあるコマンドを打っていけばいいのでは?(筋肉で解決)


解説

公式の解説が丁寧なのでそちらを参照。

解説に対するメモ

  • 'DML' = Data Manipulation Language(select文、insert文など)参考
  • --base64-output=DECODE-ROWS はバイナリログが元々ROW形式なので読めるようにするためにつける。
  • -vv = --verbose --verbose (詳細なメッセージを表示)
  • -- CHANGE MASTER TO MASTER_LOG_FILE='binlog.000018', MASTER_LOG_POS=34626719;binlog.00001834626719が大事。
  • binlog.000018 からバックアップ後のデータを復旧する。
  • startpositionは34626719 になる。
  • mysqlbinlog は MySQLのバイナリログの解析に使われる。

試してみた

(私の環境に合わせたコマンドにしてる)

mysqldump --password=passwordh --opt --single-transaction --master-data=2 hunadb > dump.sql

--master-data=2が大事だったとは(ちゃんと調べてなきゃ。。)参考

dump.sql-- CHANGE MASTER TO のとこの情報をバックアップ以降の更新の始まりを知るべく確認。

binlogもあったのでこれに対して

mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -vv --start-position=$MASTER_LOG_POS binlog.000002 | grep -B 10 truncate で、出てきた。

truncateを打った時のtimestampがわかったので、 問1は、select from_unixtime(timestamp);を打てば良さそう。

mysqlbinlog --no-defaults --start-position=$MASTER_LOG_POS --stop-position=$timestamp binlog.000018 | mysql -u root -p で、復旧の手順は行えることが確認できたと思う。(最初の設定ミスってて、データのバックアップをとってすぐにtrancateしたので確認できなかった😂)

感想

全然違くて🥺 DBの授業取ってたのに🥺

採点基準

  • 問1: 30%
  • 問2: 70%