使用二进制日志进行时间点恢复
本节说明使用二进制日志执行时间点恢复的一般思路。下一节 第7.5.2节“使用事件位置进行时间点恢复”,通过示例详细说明了该操作。
本节和下一节中的许多示例都使用 mysql客户端来处理mysqlbinlog生成的二进制日志输出。如果您的二进制日志包含\0
(空)字符,则除非使用该 选项调用它,否则mysql无法解析该输出--binary-mode
。
时间点恢复的信息源是在完整备份操作之后生成的二进制日志文件集。因此,要使服务器恢复到某个时间点,必须在其上启用二进制日志记录,这是MySQL 8.0的默认设置(请参见第5.4.4节“二进制日志”)。
要从二进制日志还原数据,必须知道当前二进制日志文件的名称和位置。默认情况下,服务器在数据目录中创建二进制日志文件,但是可以使用--log-bin
将文件放置在其他位置的选项来指定路径名 。要查看所有二进制日志文件的列表,请使用以下语句:
<span style="color:#555555"><span style="color:#000000"><code class="language-sql"><span style="color:#a67f59">mysql></span> <span style="color:#0077aa">SHOW</span> <span style="color:#834689">BINARY</span> <span style="color:#0077aa">LOGS</span><span style="color:#999999">;</span></code></span></span>
要确定当前二进制日志文件的名称,请发出以下语句:
<span style="color:#555555"><span style="color:#000000"><code class="language-sql"><span style="color:#a67f59">mysql></span> <span style="color:#0077aa">SHOW</span> <span style="color:#0077aa">MASTER</span> <span style="color:#0077aa">STATUS</span><span style="color:#999999">;</span></code></span></span>
该mysqlbinlog可以实用的二进制格式的二进制日志文件中的事件转换为文本,以便他们可以查看或应用。mysqlbinlog具有用于根据事件时间或事件在日志中的位置选择二进制日志的各个部分的选项。请参见 第4.6.8节“ mysqlbinlog-用于处理二进制日志文件的实用程序”。
应用来自二进制日志的事件会使它们代表的数据修改重新执行。这样就可以恢复给定时间范围内的数据更改。要应用二进制日志中的事件,请使用mysql客户端处理 mysqlbinlog输出 :
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <em>binlog_files</em> | mysql <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span></code></span></span>
如果二进制日志文件已经过加密(可以从MySQL 8.0.14开始执行),则mysqlbinlog无法像上面的示例一样直接读取它们,但是可以使用--read-from-remote-server
(-R
)选项从服务器读取它们 。例如:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <span style="color:#990055">--read-from-remote-server</span> <span style="color:#990055">--host</span><span style="color:#0077aa"><span style="color:#999999">=</span><em>host_name</em></span> <span style="color:#990055">--port</span><span style="color:#0077aa"><span style="color:#999999">=</span>3306</span> <span style="color:#990055">--user</span><span style="color:#0077aa"><span style="color:#999999">=</span>root</span> <span style="color:#990055">--password</span> <span style="color:#990055">--ssl-mode</span><span style="color:#0077aa"><span style="color:#999999">=</span>required</span> <em>binlog_files</em> | mysql <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span></code></span></span>
在这里,该选项--ssl-mode=required
已用于确保二进制日志文件中的数据在传输中受到保护,因为该数据以未加密的格式发送到 mysqlbinlog。
当需要在执行事件之前确定事件时间或位置以选择部分日志内容时,查看日志内容会很有用。要查看日志中的事件,请将mysqlbinlog输出发送 到分页程序中:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <em>binlog_files</em> | more</code></span></span>
或者,将输出保存在文件中,然后在文本编辑器中查看文件:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <em>binlog_files</em> > tmpfile
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> ...</span> <em>edit tmpfile</em> <span style="color:#999999">.</span><span style="color:#999999">.</span><span style="color:#999999">.</span></code></span></span>
将输出保存在文件中对于在删除某些事件(例如意外事件)时执行日志内容的准备工作很有用DROP TABLE
。您可以从文件中删除任何不执行的语句,然后再执行其内容。编辑文件后,按如下所示应用内容:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysql</span> <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span> < tmpfile</code></span></span>
如果要在MySQL服务器上应用多个二进制日志,那么安全的方法是使用与服务器的单个连接来处理它们。这是一个示例,说明什么可能是不安全的:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> binlog<span style="color:#999999">.</span>000001 | mysql <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span> <span style="color:slategray"># DANGER!!</span>
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> binlog<span style="color:#999999">.</span>000002 | mysql <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span> <span style="color:slategray"># DANGER!!</span></code></span></span>
如果第一个日志文件包含一条CREATE TEMPORARY TABLE
语句,第二个日志包含使用临时表的语句,则使用与服务器的不同连接以这种方式处理二进制日志会导致问题 。当第一个 mysql进程终止时,服务器删除临时表。当第二个mysql 进程尝试使用该表时,服务器报告 “未知表”。”
为避免出现此类问题,请使用单个 连接来应用要处理的所有二进制日志文件的内容。这是一种方法:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> binlog<span style="color:#999999">.</span>000001 binlog<span style="color:#999999">.</span>000002 | mysql <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span></code></span></span>
另一种方法是将整个日志写入单个文件,然后处理该文件:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> binlog<span style="color:#999999">.</span>000001 > /tmp/statements<span style="color:#999999">.</span>sql
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> binlog<span style="color:#999999">.</span>000002 >> /tmp/statements<span style="color:#999999">.</span>sql
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysql</span> <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span> <span style="color:#990055">-e</span> <span style="color:#0077aa">"source /tmp/statements.sql"</span></code></span></span>
在从包含GTID的二进制日志中读回时写入转储文件时(请参见第17.1.3节“使用全局事务标识符进行复制”),请将该--skip-gtids
选项与 mysqlbinlog一起使用,如下所示:
<span style="color:#555555"><span style="color:#000000"><code class="language-terminal"><span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <span style="color:#990055">--skip-gtids</span> binlog<span style="color:#999999">.</span>000001 > /tmp/dump<span style="color:#999999">.</span>sql
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysqlbinlog</span> <span style="color:#990055">--skip-gtids</span> binlog<span style="color:#999999">.</span>000002 >> /tmp/dump<span style="color:#999999">.</span>sql
<span style="color:#a67f59">shell></span><span style="color:#0077aa"> mysql</span> <span style="color:#990055">-u</span> root <span style="color:#990055">-p</span> <span style="color:#990055">-e</span> <span style="color:#0077aa">"source /tmp/dump.sql"</span></code></span></span>