mysql怎么做一个数据库复制到另一个mysql服务器 不借助任何工具,纯sql语句

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql怎么做一个数据库复制到另一个mysql服务器 不借助任何工具,纯sql语句相关的知识,希望对你有一定的参考价值。

假设我要从127.0.0.1的机器的mysql服务器的test1数据库 到127.0.0.2的mysql上复制一份test1数据库怎么做,要表结构,视图,函数,触发规则,配置全都完全迁移

直接在执行器里运行sql语句的好像是没有的,可以用备份和还原命令语句,也能远程备份和还原的,在程序命令库里就能执行,windows和linux都可以。

备份:mysqldump -h 127.0.0.1 -u root -p test1 > sql_bak.sql

还原:mysql -h 127.0.0.2 -u root -p -P 3306 test1< sql_bak.sql
参考技术A 纯sql貌似不行,还是要用sql里面的备份恢复 参考技术B 命令行执行mysqldump -h 127.0.0.1 -uroot -ppassword test1 | mysql -h 127.0.0.2 -uroot -ppassword test1追问

这个可以复制触发规则和视图,函数吗

追答

加上-R就是复制存储过程及自定义函数 --triggers 是复制触发器,视图就是mysql的临时表可以复制的

参考技术C

每当我们讨论一项(新的)领域技术的时候,最好的方式通常是首先抛出一些问题,这些问题大致分为三类:


    诶?这项技术又是什么玩意(What)?

    这项技术为什么会存在?我们已经有那么多解决方案(Method)了,我们为什么要用它(Why)?

    如果这项技术那么好且我们正好有场景可以用到这项技术,且能使我们的系统得到很乐观的优化,那么我们怎么用呢(How)?


    大概已经有同学觉得这些问题很熟悉了,是的,这就是黄金全法则提出的三个问题,对于每种新鲜事物我们首先基于这三个问题去了解,更有利于弄清楚事情的本质,端正态度去了解,而不是因为新,因为大家都说好,才要去了解……。说了那么多前奏,我们可以开始了,今天我们就带着黄金圈法则提出的三个问题去看看MySQL数据库复制这项领域技术,然后再结合实际应用扩展一些问题,本文也仅仅是结合自己了解的皮毛以抛砖引玉的态度和大家一起分享。

    WHAT?

    MySQL复制使得一台MySQL数据库服务器的数据被拷贝到其他一台或者多台数据库服务器,前者通常被叫做Master,后者通常被叫做Slave。

    MySQL复制示意图

    复制的结果是集群(Cluster)中的所有数据库服务器得到的数据理论上都是一样的,都是同一份数据,只是有多个copy。MySQL默认内建的复制策略是异步的,基于不同的配置,Slave不一定要一直和Master保持连接不断的复制或等待复制,我们指定复制所有的数据库,一部分数据库,甚至是某个数据库的某部分的表。

    MySQL复制支持多种不同的复制策略,包括同步、半同步、异步和延迟策略等。

    同步策略:Master要等待所有Slave应答之后才会提交(MySql对DB操作的提交通常是先对操作事件进行二进制日志文件写入然后再进行提交)。

    半同步策略:Master等待至少一个Slave应答就可以提交。

    异步策略:Master不需要等待Slave应答就可以提交。

    延迟策略:Slave要至少落后Master指定的时间。

    MySQL复制同时支持多种不同的复制模式:

    基于语句的复制,Statement Based Replication(SBR)。

    基于行的复制Row Based Replication(RBR)。

    混合复制(Mixed)。

    WHY?

    这个问题其实也就是MySQL复制有什么好处,我们可以将复制的好处归结于下面几类:

    性能方面:MySQL复制是一种Scale-out方案,也即“水平扩展”,将原来的单点负载扩散到多台Slave机器中去,从而提高总体的服务性能。在这种方式下,所有的写操作,当然包括UPDATE操作,都要发生在Master服务器上。读操作发生在一台或者多台Slave机器上。这种模型可以在一定程度上提高总体的服务性能,Master服务器专注于写和更新操作,Slave服务器专注于读操作,我们同时可以通过增加Slave服务器的数量来提高读服务的性能。

    防腐化:由于数据被复制到了Slave,Slave可以暂停复制进程,进行数据备份,因此可以防止数据腐化。

    故障恢复:同时多台Slave如果有一台Slave挂掉之后我们还可以从其他Slave读取,如果配置了主从切换的话,当Master挂掉之后我们还可以选择一台Slave作为Master继续提供写服务,这大大增加了应用的可靠性。

    数据分析:实时数据可以存储在Master,而数据分析可以从Slave读取,这样不会影响Master的性能。

    HOW?

    这里我们只介绍一下MySQL的复制是如何工作的,至于配置,网上也有很多相关的介绍,读者具体应用的时候可以再去查阅。我们拿最常用的基于二进制文件的复制来看看。

    MySQL复制工作示意图

    请点击输入图片描述

    请点击输入图片描述

    MySQL的复制过程大概如下:

    首先,主库在每次准备提交事务完成数据更新操作之前都会将数据更改操作记录到二进制日志中,这些日志是以二进制的方式记录数据更改的事件。值得一提的是二进制日志中记录的顺序实际上是事务的提交顺序,而非SQL执行语句的顺序。在记录二进制日志之后,主库会告诉存储引擎事务可以提交了。

    然后,备库会启动一个IO线程,之所以叫做IO线程是因为这个线程专门做IO相关的工作,包括和主库建立连接,然后在主库上启动一个特殊的二进制转储线程,这个转储线程会不断的读取二进制日志中的事件,发送给备库的IO线程,备库的IO线程会将事件记录到中继日志中。

    备库会有一个叫做SQL的线程被开启,这个线程做的事情是读取中继日志中的DB操作事件在备库执行,从而实现数据更新。

    总的来说,在发生复制的主库服务器和备库服务器中,一共有三个线程在工作。

    上面我们已经大概了解的什么是复制?为什么要复制?如何复制?这三个问题了,接下来我们基于上面的介绍,提出一些实际应用可能会发生的问题来思考如何解决。博主自问自答的方式-。-

    问答环节

    问题一:通过复制模型虽然读能力可以通过扩展slave机器来达到提高,而写能力却不能,如果写达到瓶颈我们应该怎么做呢?

    答:我们首先会得出结论,这种复制模型对于写少读多型应用是非常有优势的,其次,当遇到这种问题的时候我们可以对数据库进行分库操作,所谓分库,就是将业务相关性比较大的表放在同一个数据库中,例如之前数据库有A,B,C,D四张表,A表和B表关系比较大,而C表和D表关系比较大,这样我们把C表和D表分离出去成为一个单独的数据库,通过这种方式,我们可以将原有的单点写变成双点写或多点些,从而降低原有主库的写负载。

    问题二:因为复制是有延迟的,肯定会发生主库写了,但是从库还没有读到的情况,遇到这种问题怎么办?

    答:MySQL支持不同的复制策略,基于不同的复制策略达到的效果也是不一样的,如果是异步复制,MySQL不能保证从库立马能够读到主库实时写入的数据,这个时候我们要权衡选择不同复制策略的利弊来进行取舍。所谓利弊,就是我们是否对从库的读有那么高的实时性要求,如果真的有,我们可以考虑使用同步复制策略,但是这种策略相比于异步复制策略会大大降低主库的响应时间和性能。我们是否可以在应用的设计层面去避开这个问题?

    问题三:复制的不同模式有什么优缺点?我们如何选择?

    答:基于语句的复制实际上是把主库上执行的SQL在从库上重新执行一遍,这么做的好处是实现起来简单,当前也有缺点,比如我们SQL里面使用了NOW(),当同一条SQL在从库中执行的时候显然和在主库中执行的结果是不一样的,注入此类问题可以类推。其次问题就是这种复制必须是串行的,为了保证串行执行,就需要更多的锁。

    基于行的复制的时候二进制日志中记录的实际上是数据本身,这样从库可以得到正确的数据,这种方式缺点很明显,数据必须要存储在二进制日志文件中,这无疑增加的二进制日志文件的大小,同时增加的IO线程的负载和网络带宽消耗。而相比于基于语句的复制还有一个优点就是基于行的复制无需重放查询,省去了很多性能消耗。

    无论哪种复制模式都不是完美的,日志如何选择,这个问题可以在理解他们的优缺点之后进行权衡。

    问题四:复制的工作过程只有三个线程来完成,对于Master来说,写是并发的,也就出现了一个IO线程要把所有并发的数据变更事件记录,这个IO线程会不会累死?当一个Master对应多个Slave的时候,其实在Master中会唤起多个IO线程,这无疑会增加Master的资源开销,如果出现事件堆积,也就是事件太多,来不及及时发送出去怎么办?另外就是Slave那边的IO线程和SQL线程也会有对应主库并发数据变更事件,而Slave方单个线程处理的问题,这个时候Slave线程会不会累死?

    答:上面的问题确实会发生,上面第一个问题和第二个问题其实是写负载的问题,当事件堆积太多,从库时延就会变大,Slave单SQL线程问题据说有参数可以开启并行操作,这个大家可以确认一下。

    问题五:针对复制工作过程可能会出现的问题,主库写完二进制日志文件同时都会保存二进制日志的偏移量,但是当断电的时候,二进制日志文件没有刷新到磁盘,主库重新启动之后,从库尝试读该偏移量的二进制日志,会出现读不到的情况,这个问题应该怎么解决?

    答:首先如果开启了sync_binlog选项,对于innodb同时设置innodb_flush_log_at_trx_commot=1,则可以保证二进制日志文件会被写入磁盘,但MyISAM引擎可能会导致数据损坏。如果没有开启这个选项,则可以通过制定从库的二进制偏移量为下一个二进制日志文件的开头,但是不能解决事件丢失问题。

    问题六:从库在非计划的关闭或重启时,回去读master.info文件去找上次停止复制的位置,这同样会有一个问题,如果master.info不正确,就会导致复制数据不一致的情况,遇到这个问题怎么办?

    答:这个问题可以通过两种方式解决,一是控制master.info在从库非计划关闭或重启的时候让master.info能够同步到磁盘,这样下次启动的时候就不会读取错误的信息,这有助于减少错误的发生概率。另外想要找到正确的复制位置是困难的,我们也可以选择忽略错误。

    请点击输入图片描述

    请点击输入图片描述

如何复制MySQL数据库或表到另外一台服务器

使用这种方法前,我们需要先下载一个MySQL客户端工具SqlYog。点击这里下载并安装

下面我们开始复制数据库:
1、打开SqlYog community Edition,分别在不同的选项卡中打开源数据库服务器与目标数据库服务器,这一点很重。

在源数据库服务器选项卡中你将看到所有数据库列表。
2、在需要复制迁移的数据库上右击,在弹出菜单中选择“Copy Database to Different Host/Database”
3、在弹出对话框中,我们能看到源数据库服务器及目标服务器,在左边,通过勾选复选框来选择需要复制迁移的对象,如表、函数、触发器等,也可以选择所有对象。
4、在右边选择需要迁移的目标服务器或数据库
5、根据你的需要选择复制类型:“Structure and Data”或“Structure only”,即“结构和数据”或“仅结构”。
6、选择结束后点击“Copy”按钮开始复制,知道数据迁移结束。
参考技术A 1、如果系统和mysql版本都一致,你可以直接把mysql打个包,放到另一台服务器上去后,启动mysql即可使用
2、或者只复制数据库目录,但是得看表用的哪种存储结构,例如data/db01
3、或者只复制表,也得看表用的哪种存储结构,例如data/db01/user01.*
4、或者用mysqldump导出数据,mysql导入数据,例如:
mysqldump -uuser01 -p123456 db01 > db01.sql
恢复数据
mysql -uuser01 -p123456 -Ddb01 < db01.sql
参考技术B

MySQL 8.0.17 clone 插件的安装和验证过程

安装非常简单,与安装其他插件的工作方式相同。下面是安装克隆插件的命令行:

   master [localhost:45008] ((none)) > INSTALL PLUGIN clone SONAME 'mysql_clone.so';Query OK, 0 rows affected (0.00 sec)
以及如何检查克隆插件是否处于活动状态:master [localhost:45008] ((none)) > SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINSWHERE PLUGIN_NAME LIKE 'clone';+-------------+---------------+| PLUGIN_NAME | PLUGIN_STATUS |+-------------+---------------+| clone | ACTIVE |+-------------+---------------+1 row in set (0.00 sec)
请注意,这些步骤需要在 Donor(供体)和 Recipient(受体,也成为 Slave)上都执行。执行安装后,插件将在重新启动后自动加载,因此您不必再担心这一点。接下来,我们将在 Donor 上创建具有必要权限的用户,这样我们就可以远程连接到实例来克隆它。

    master [localhost:45008] ((none)) > create user clone_user@'%' identified by 'sekret';

    Query OK, 0 rows affected (0.01 sec)

    master [localhost:45008] ((none)) > GRANT BACKUP_ADMIN ON *.* TO 'clone_user'@'%';

    Query OK, 0 rows affected (0.00 sec)

    作为安全措施,我建议将百分号 % 替换为从机的 IP、主机名或网络掩码,以便只有未来的从服务器才能接受连接。现在,从服务器上,克隆用户需要CLONE_ADMIN 权限来替换从机数据,在克隆操作期间阻止 DDL 并自动重新启动服务器。

    slave1 [localhost:45009] ((none)) > create user clone_user@'localhost' identified by 'sekret';

    Query OK, 0 rows affected (0.01 sec)

    slave1 [localhost:45009] ((none)) > GRANT CLONE_ADMIN ON *.* TO 'clone_user'@'localhost';

    Query OK, 0 rows affected (0.00 sec)

    接下来,安装并验证插件,并在主和从服务器上创建用户。


    克隆过程

    如上所述,克隆过程可以在本地或远程执行。此外,它支持复制,这意味着克隆操作从捐赠者提取和传输复制坐标并将其应用于收件人。它可用于 GTID 或非 GTID 复制。因此,要开始克隆过程,首先,让我们确保有一个有效的供体(Master)。这由 clone_valid_donor_list 参数控制。由于它是动态参数,您可以在服务器运行时进行更改。使用 show variables 命令将显示参数是否具有有效的供体(Master):slave1 [localhost:45009] ((none)) > SHOW VARIABLES LIKE 'clone_valid_donor_list';+------------------------+-------+| Variable_name | Value |+------------------------+-------+| clone_valid_donor_list | |+------------------------+-------+1 row in set (0.01 sec)


    例子中,我们需要对它进行设置:slave1 [localhost:45009] ((none)) > set global clone_valid_donor_list = '127.0.0.1:45008';Query OK, 0 rows affected (0.00 sec)


    下一步不是强制性的,但使用默认的 log_error_verbosity,错误日志不会显示有关克隆进度的大量信息。所以,对于这个例子,我会将详细程度调整到更高的级别(在供体和受体机上):mysql > set global log_error_verbosity=3;Query OK, 0 rows affected (0.00 sec)


    现在,让我们在受体(Slave)上开始克隆过程:slave1 [localhost:45009] ((none)) > CLONE INSTANCE FROM clone_user@127.0.0.1:45008 identified by 'sekret';Query OK, 0 rows affected (38.58 sec)


以上是关于mysql怎么做一个数据库复制到另一个mysql服务器 不借助任何工具,纯sql语句的主要内容,如果未能解决你的问题,请参考以下文章

如何复制mysql数据库到另一台电脑上?

mysql如何把同一张表的一个字段内的内容复制到另一个字段里

MYSQL数据库中的一个表怎么复制到新建的一个数据库里?

mysql 数据库怎么复制一张表?

如何复制mysql数据库到另一台电脑上?

[MySql]如何将一行从一个表复制到另一个并填充额外的列?