SQL Server 2012所支持的Always On技术集中了故障转移群集、数据库镜像和日志传送三者的优点,但又不相同。故障转移群集的单位是SQL实例,数据库镜像和日志传送的单位是单个用户数据库,而Always On支持的单位是可用性组,每个组中可以包括一个或者是多个用户数据库。也就是说,一旦发生切换,则可用性组中的所有数据库会作为一个整体进行切换。
Always On底层依然采用Windows 故障转移群集的机制进行监测和转移,因此也需要先建立Windows Cluster,只不过可用性组中的数据库不一定非要再存放在共享存储上了,可以存储在本地磁盘上。
Always On最多可以支持8个副本,但只有一个可用性副本上运行的数据库是处于可读写状态。这个可读写的数据库被称为主数据库(Primary Database),同时这个可用性副本被称为主副本(Primary replica),其余的副本都被称为辅助副本(Secondary replica),辅助副本上的数据库可能是不可访问的,或者是只能接受只读操作(取决于可用性组的配置),这些数据库被称为辅助数据库。一但发生故障转移,任何一个辅助副本都可以成为新的主副本实例。主副本会不断地将主数据库上的数据变化发送到辅助副本,来实现副本间的数据库同步。
下面,先来了解下Always On的关键特性:
1. 同故障转移群集一样,也需要一个虚拟网络名称用于客户端的统一连接。
2.一个主服务器最多对应8个辅助服务器,且它们支持只读功能,通过配置可以实现读写分离。
3.辅助服务器可以独立执行备份和DBCC维护命令。
4.主服务器和辅助服务器之间的数据会被加密和压缩,以提高安全性和网络传输效率。
5.支持自动、手动和强制三种故障转移方式。
6.有仪表盘用于监控Always On的运行状态。
7.可以实现多站点的部署,即主站点和辅助站点可以跨物理网络。
Always On的基本架构
在Windows 故障转移群集的基础上部署Always On高可用组,用户可以在群集节点上安装SQL Server单机实例,也可以安装SQL Server群集实例。可用性副本是单机实例,那么数据库副本就存放在运行该实例节点的本地磁盘上;如果可用性副本是群集实例,那么数据库副本就存放在共享磁盘上。
可用性组从Windows群集角度来看,就是一个群集资源,其中的所有数据库作为一个整体在节点间进行故障转移,当然这不包括系统数据库,系统数据库是不能加入高可用性组中的。
因为需要借助Windows群集实现监控和转移,所以Always On会受到一些限制:
- 一个可用性组中的所有可用性副本必须运行在单一的Windows群集上,跨不同Windows群集的SQL Server实例不能配置成一个Always On可用性组。
- 一个可用性组的所有可用性副本必须运行在Windows群集的不同节点上。运行在同一个节点上的两个不同实例不能用作同一个可用性组的副本。
- 如果某个可用性副本实例是一个SQL群集实例,那同一个SQL群集的其他非活跃节点上安装的任何其他SQL实例都不能作为它的辅助副本。
- 一个数据库只能属于一个可用性组。
侦听器Listener
Always On创建后,客户端就需要进行连接,为了让应用程序能够透明地连接到主副本而不受故障故障转移的影响,我们需要创建一个侦听器,侦听器就是一个虚拟的网络名称,包括虚拟IP地址、虚拟网络名称、端口号三个元素。一旦创建成功,虚拟网络名称会注册到DNS中,同时为可用性组资源添加IP地址资源和网络名称资源,用户就可以通过这个虚拟网络名称访问可用性组,而不用关心连接的是哪一个节点,它会自动将请求转发到主节点,当主节点发生故障后,辅助节点会变为主节点,侦听器也会自动去侦听主节点。与故障转移群集不同,除了使用虚拟网络名称之外,主副本的真实实例名也可以被用来连接。
SQL Server 2012允许在副本实例处于运行状况的时候随时绑定新的IP地址、网络名称和端口号。因此可以随时为可用性组添加侦听器,而且这个操作会立即生效。
要注意的是,SQL Browser服务是不支持Listener的。这是因为应用程序在使用Listener的虚拟网络名连接SQL Server时,是以一个默认实例的形式进行访问的(只有主机名,没有实例名),因此客户端根本就不会去尝试使用SQL Browser服务。
各副本间的数据同步
Always On必须要维护各副本间的数据一致性,当主副本上的数据发生变化,会同步到辅助副本上。在主副本和辅助副本上,SQL Server都会启动相应的线程来完成相应的任务。对于一般的SQL Server服务器,即没有配置高可用性,会运行Log Writer的线程,当发生数据修改事务时,此线程负责将本次操对应的日志信息记录到日志缓冲区中,然后再写入到物理日志文件。但如果配置了Always On主副本的数据库,SQL Server会为它建立一个叫Log Scanner的线程,不间断的工作,负责将日志从日志缓冲区或日志文件里读出,打包成日志块,发送到辅助副本。因此可以保证发生的数据变化,不断送给各辅助副本。
辅助副本上存在固化和重做两个线程完成数据更新操作,固化线程会将主副本Log Scanner所发过来的日志块写入辅助副本磁盘上的日志文件里,因此称为固化,然后重做线程负责从磁盘上读取日志块,将日志记录对应的操作重演一遍,此时主副本和辅助副本上的数据就一致了。重做线程每隔固定的时间点,会跟主副本通信,告知自己的工作进度,主副本由此知道两边数据的差距。Log Scanner负责传送日志块,不需要等待Log Writer完成日志固化;辅助副本完成日志固化以后就会发送消息到主副本,告知数据传输完成,而不需要等待重做完成,这样各自独立的设计,是尽可能减少 Always On所带来的操作对数据库性能的影响。