什么是主从复制
主从复制是指将一个数据库服务器上的数据复制到另一个或多个服务器上,这些服务器被称为从服务器。主服务器和从服务器之间的关系是一种基于主从复制的方式。它的主要作用是使得从服务器可以拥有和主服务器一样的数据。
为什么需要主从复制
在实际应用中,有些应用的读写比例非常不均衡,读操作远远大于写操作,而且很多读操作并不需要实时性。这种情况下,可以采用主从复制的方式,将读操作分摊到各个从服务器上,从而减轻主服务器的负担,提高读性能。
主从复制如何工作
1. 主服务器将所有的更新操作记录在二进制日志中
当主服务器收到一个更新请求时,它将该操作记录在二进制日志中。在主从复制中,二进制日志是非常重要的,因为它是从服务器复制数据所必须使用的。二进制日志记录了所有的更新操作,包括增、删、改、DDL等。二进制日志是一种紧凑的二进制文件,能够很有效地记录操作日志,而且可以方便地进行备份和恢复。
2. 从服务器连接主服务器,并请求获取二进制日志
从服务器向主服务器发起连接请求,并请求获取主服务器上指定的二进制日志。主从服务器之间的连接通常采用TCP/IP协议,这种连接是可靠的。从服务器在连接主服务器之后,会从主服务器上开始获取二进制日志,并在本地应用这些操作,保持与主服务器上的数据一致。
3. 从服务器处理二进制日志,并将更新操作应用到本地数据库中
从服务器将从主服务器上获取到的二进制日志进行处理,并将其中的更新操作应用到本地数据库中。因为主从服务器之间的通信是异步的,所以从服务器上的数据并不是时时刻刻与主服务器上的数据完全一致。但是,在一般情况下,这种差异是可以忽略的。
4. 从服务器定期向主服务器发送心跳包
为了确保主从服务器之间的连接是稳定可靠的,从服务器会定期向主服务器发送心跳包,以检测连接是否正常。如果从服务器在一段时间内没有收到来自主服务器的回应,就会认为连接已经断开,需要重新连接。
主从复制的实现方式
在MySQL中,主从复制有两种实现方式,分别是基于语句的复制和基于行的复制。基于语句的复制是指主从服务器之间复制的是SQL语句,而不是记录的实际数据内容。基于行的复制是指主从服务器之间复制的是记录的实际数据内容,而不是SQL语句。
1. 基于语句的复制
基于语句的复制可以完全复制主服务器上的操作,并且对主从服务器之间通信的压力很小。但是,基于语句的复制也存在一些限制。例如,在主服务器上执行一些特定的语句时,可能会导致从服务器上的数据与主服务器对不上。
在MSSQL Server中,基于语句的复制可以实现数据库级别的操作。在MSSQL中,可以通过以下代码来创建一个基于语句的复制:
EXEC sp_addpublication @publication = N'Repl_Pub',
@description = N'Transactional publication of database ''Repl_Demo'' from Publisher ''server1''',
@sync_method=N'Native',
@retention=14,
@allow_push=N'True',
@allow_pull=N'True',
@allow_anonymous=N'False',
@enabled_for_internet=N'False',
@snapshot_in_defaultfolder=N'True',
@compress_snapshot=N'False',
@ftp_port=21,
@ftp_login=N'',
@ftp_password=N'',
@allow_subscription_copy=N'False',
@add_to_active_directory=N'False',
@repl_freq=N'continuous',
@status=N'active',
@independent_agent=N'True',
@immediate_sync=N'False',
@allow_sync_tran=N'False',
@autogen_sync_procs=N'False',
@allow_queued_tran=N'False',
@allow_dts=N'False',
@replicate_ddl=N'False',
@allow_initialize_from_backup=N'False',
@enabled_for_p2p=N'False',
@enabled_for_het_sub=N'False'
GO
EXEC sp_addpublication_snapshot @publication = N'Repl_Pub',
@frequency_type = 1,
@frequency_interval = 0,
@frequency_relative_interval = 0,
@frequency_recurrence_factor = 0,
@frequency_subday = 0,
@frequency_subday_interval = 0,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@job_login = null,
@job_password = null,
@publisher_security_mode = 1
EXEC sp_addpublication_reinitialization @publication = N'Repl_Pub',
@sync_type = N'automatic',
@replicate_partition_switch = N'false',
@allow_subscription_reinitialization = N'false',
@restart_on_error = N'false',
@allow_synctoalternate = N'false',
@max_concurrent_repljobs = 0,
@max_parallelism = 0,
@use_interactive_resolver = N'false'
GO
2. 基于行的复制
基于行的复制可以更加精确地复制操作,而且不会出现基于语句的复制的限制。但是,基于行的复制通常需要对主从服务器之间的通信进行压缩,以减少数据传输量。
在MSSQL Server中,基本上所有的数据类型都支持基于行的复制。基于行的复制非常适合大数据量、高并发的应用场景。在MSSQL中,可以通过以下代码来创建一个基于行的复制:
USE [master]
GO
EXEC sp_addsubscription @publication = N'Repl_Pub',
@subscriber = N'server2',
@destination_db = N'Repl_Demo',
@subscription_type = N'Push',
@sync_type = N'automatic',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0
GO
主从行锁实现事务安全
在MSSQL Server中,主从复制可以使用行锁来实现事务的安全性。行锁是指在访问某一个表中的某些行时,对这些行进行加锁,从而防止其他用户修改或删除这些行。留下这些行的副本并不重要,重要的是确保在提交事务之前不会有其他用户修改或删除这些行。
在MSSQL Server中,可以使用锁定协调器(Lock Coordinator)来完成行锁的实现。当有多个客户端同时对同一个表进行修改时,锁定协调器将会对这些修改进行协调,以确保操作的正确性和一致性,在保证事务处理的并发性的同时,保证了数据的安全性。