分类 技术 Technology 下的文章

MySQL 是一个小型关系型数据库管理系统,被广泛用于各种中小 Web 应用中。常见的应用架构有:

1、单点(Single):适合小规模应用;
2、复制(Replication):适合中小规模应用;
3、集群(Cluster):适合大规模应用。

曾写过 httpd 服务端与 MySQL 数据库分开部署的情况的文章,那属于单点应用的范畴。而随着业务需求的不断增长,更高的负载量、更安全的系数、更可靠的存储,这一切都会让依然停留在单点应用的你举步维艰。

令人高兴的是,MySQL 早在 3.23.15 版本开始就提供了单向的异步复制功能。利用该功能可以实现两种数据库异步复制:主从模式(A -> B,或 A -> B、C、D)、互相备份模式(A <=> B)。后者也称“双向热备”或“双机热备”,是前者的扩展与补充。

值得注意的是,这种复制是异步的,有别于 MySQL 的同步复制实现(也称做 MySQL 集群、MySQL Cluster,本文不作讨论,感兴趣的话可参见这里)。

相关原理:当主库有更新的时候,主库会把更新操作的 SQL 写入二进制日志 (Bin log),并维护一个二进制日志文件的索引,以便于日志文件轮回(Rotate)。在从库启动异步复制的时候,从库会开启两个 I/O 线程,其中一个线程连接主库,要求主库把二进制日志的变化部分传给从库,并把传回的日志写入本地磁盘。另一个线程则负责读取本地写入的二进制日志,并在本地执行,以反映出这种变化。较老的版本在复制的时候只启用一个 I/O 线程,实现这两部分的功能。

需要注意的地方:

1、主库必须启用 Bin log,主库和从库必须有唯一的 Server Id;
2、从库必须清楚了解从主库的哪一个 Bin log 文件的哪一个偏移位置起开始复制;
3、从库可以从主库只复制指定的数据库,或者数据库的某些数据表;
4、主库和从库的数据库名称可以不一样,不过还是推荐使用一样的名称;
5、主库和从库的 MySQL 版本需保持一致。

由于 MySQL 复制功能的设置都在其配置文件 my.cnf 中体现,因此互相备份模式与主从模式大同小异。本文所涉方案为后者。

首先分别在两台服务器上下载、解压缩版本相同的 MySQL 源码包,并编译安装。此过程在此略过,并假设:

1、两台机器在同一子网内,且 IP 地址分别为 192.168.0.31(以下简称 A 机器) 与 192.168.0.15(以下简称 B 机器);
2、两台机器的数据库版本、目录、初始的库、表均一致;
3、MySQL 配置文件都位于 /etc/my.cnf;
4、需要同步的库:dbname,不需要同步的库:mysql、test。

在 A 机器上添加 mysqlrepl 为同步帐号:

GRANT REPLICATION SLAVE ON *.* TO 'mysqlrepl'@'192.168.0.15' IDENTIFIED BY '密码'; 然后:

vi /etc/my.cnf 修改:

# 日志的名称
log-bin=mysql-bin
# 主服务器 ID
server-id=1
# 需要备份的库
binlog-do-db=dbname
# 忽略的库
binlog-ignore-db=mysql
binlog-ignore-db=test
在 B 机器上:

vi /etc/my.cnf 修改:

# 日志的名称
log-bin=mysql-bin
# 从服务器 ID
server-id=2
# 主服务器的 IP 地址或者域名
master-host=192.168.0.31
# 主数据库的端口号
master-port=3306
# 同步数据库的用户
master-user=mysqlrepl
# 同步数据库的密码
master-password=
# 如果从服务器发现主服务器断开,重新连接的时间差(秒)
master-connect-retry=30
# 需要同步的库
replicate-do-db=dbname
# 忽略的库
replicate-ignore-db=mysql
replicate-ignore-db=test
重启两边的 MySQL,在 B 机器上登入 mysqld,执行:

mysql>slave start; 然后可以查看同步配置情况。在 A 机器上执行:

mysql>show master status; 在 B 机器上执行:

mysql>show slave status; 截止这里,我们只实现了 A -> B 的复制,要实现双向热备,仅需要将上面的步骤倒过来执行一遍即可。

如果要问系统管理员最痛恨的事情是什么,我敢打赌,99%的回答不是遇到棘手的问题,也不是遇到莫名其妙的情况,而是给那些该死的 Windows 系统服务器打补丁——一个一个又一个,一台一台又一台,一遍一遍又一遍……生生不息、永无止境。

不要告诉我有 WSUS 这个玩意,我知道。这个鬼东西和域控制器建在一起,那简直就是地狱。至今我依然不记得在同一台服务器上应该先安装 WSUS,还是先搭建域控制器。总之它们俩必定有一个先后顺序,不然会影响对方——我很佩服微软,真的。

幸好伟大的 M$ 公司还有一个玩意叫做批处理脚本。下面这个脚本用于批量补丁,可以帮助系统管理员节约时间,减少白头发:

FOR %%i IN (*.EXE) DO %%i /passive /norestart /nobackup 脚本需要放在那一堆补丁中间,就像羊群中的狼一样。另外参数也可以根据实际情况调整。

前几天在一台 Windows 2003 Enterprise Edition 的机器上,突然运行不了这个脚本,提示:

Windows 无法访问指定设备、路径或文件。您可能没有合适的权限访问这个项目。 我以为我在做梦,或是眼睛模糊了。再次执行,还是一样;来到 CMD 下执行,也是一样,于是我被折服了。

看了 M$ 公司伟大的帮助文档后,才知道这样的情况乃是相当罕见。应该这样解决:

回到上层目录,右键补丁和 BAT 脚本所在的目录,选择“属性”,然后“安全”选项卡,点击下面的“高级”,选择“所有者”选项卡,选中“替换子容器及对象的所有者”,然后“应用”,接着切换到“审核”选项卡,选中“允许父项的继承审核项目传播到该对象和所有子对象。包括那些在此明确定义的项目”和“用在此显示的那些可以应用到子对象的项目替代所有子对象的审核项目”,点击“应用”,确定所有对话框,一切完成。

由于某种特殊情况,前几天又重新开始写 PHP。这次遇到一个比较有意思的问题,被要求使用 PHP 脚本验证来自某个表单的一个(请注意,是一个)文本框中的数据是否为合法的国内电话号码格式或合法的国内移动电话号码格式。

我知道这样 BT 的需求不通过正则实现恐怕是南辕北辙。而我又一向不谙正则,尤其对排列组合十分感冒。无奈之下,搜索……

首先看到 phpchina 上某位兄台的博客上的文章,貌似对常用正则表达式做了一个清晰的整理。文章上对国内电话格式合法性的验证,给出了这样的公式:

\d{3}-\d{8}|\d{4}-\d{7} 很显然,它的适用范围不够广泛。

我们来重新分析一下需求:

1、合法的国内固定电话号码格式:带有前导零的长途区号、连字符“-”(念“hyphen”,具体可参考这里)、电话号码。除此之外,还应考虑分机号码的存在。

合法格式举例:

0571-88909090
0573-6262662
021-60606060-808

- 阅读剩余部分 -

前段时间公司内部的版本库服务器存储空间吃紧,必须增加外部存储设备或者更换服务器。于是我面临了痛苦的选择:那台联想万全 T200 服役了近 10 年。早在不经意之中,就摩擦出了爱情的火花。更换服务器,她就面临着退役,我不忍;增加外存,我担心她太累,又心疼。

于是另购了一块希捷的 250GB SCSI 硬盘,拆开机箱,连上数据线和电源线,可开机后提示找不到可以启动的系统。于是重启,回到 BIOS 选项,发现硬盘根本没有被认到。我首先想到的是跳线,但不肯定 SCSI 硬盘也有跳线这样的说法。

再一次拆开机箱,拆下硬盘,重新观察了一下,确实有跳线这个东西。具体接法见下图:

重新接好,设置从老硬盘启动,终于进入 FreeBSD。接着 sysinstall,为第二块硬盘划分 partition 和 label。整个过程比较简单,值得注意的是需要 w 将信息写入。分区完成后,我是直接修改 /etc/fstab 的,也可以手动挂载,具体办法见这里

现在的启动信息:

Waiting 5 seconds for SCSI devices to settle
da0 at ahc0 bus 0 target 0 lun 0
da0: <QUANTUM ATLAS10K3_18_WLS 020W> Fixed Direct Access SCSI-3 device 
da0: 160.000MB/s transfers (80.000MHz, offset 127, 16bit), Tagged Queueing Enabled
da0: 17537MB (35916548 512 byte sectors: 255H 63S/T 2235C)
da1 at ahc0 bus 0 target 1 lun 0
da1: <SEAGATE ST3146707LW D704> Fixed Direct Access SCSI-3 device 
da1: 160.000MB/s transfers (80.000MHz, offset 63, 16bit), Tagged Queueing Enabled
da1: 140014MB (286749480 512 byte sectors: 255H 63S/T 17849C)
da2 at ahc0 bus 0 target 2 lun 0
da2: <SEAGATE ST3146707LW D704> Fixed Direct Access SCSI-3 device 
da2: 160.000MB/s transfers (80.000MHz, offset 63, 16bit), Tagged Queueing Enabled
da2: 140014MB (286749480 512 byte sectors: 255H 63S/T 17849C)
延缓死亡的手续到此结束。

随着公司业务平台不断扩大,原先数据库服务器上 2GB 的物理内存已显得较为吃紧。前段时间,一狠心,在 DELL 下了一个 PowerEdge 2950 架构的单,直接上到 4GB。

数据库服务器最在意的事情就是数据存储的安全可靠。为此我订购了四块 SAS 硬盘,其中一块做系统盘,其余三块组成一个 RAID5 阵列。这机器成本不算低了,好歹性能也跟上去了,于是日子就这么继续……

最近发现服务器的物理内存占用情况比较有意思。无论我何时连上去看,物理内存占用量都在 1.5GB 至 1.75GB 左右,死活超不过 2GB。当然,绝大部分都被 SQL Server 所占用,但没有完全占用所有可用的剩余物理内存。而 SQL Server 被配置为动态地使用所有物理内存选项。整个情况非常神奇,让我禁不住啧啧赞叹……

这神奇的景象就像这样:

网上有文章说只要打开 /3GB 或者 /PAE 开关就可以,这样的说法是不准确的。

首先我们要分析当前操作系统是什么版本,是否需要开启 /3GB 或者 /PAE 开关。具体可以参阅微软的帮助支持中心的这篇文章。我的操作系统是 Windows Server 2003 Enterprise Edition,其本身就支持最高 32 GB 的物理内存,所以不需要打开这些开关。

我个人的理解是:如果机器上的物理内存并未被操作系统所完全识别,则需要根据操作系统的实际情况考虑打开这些开关。

另外,同时使用 /3GB 和 /PAE 开关是没有意义的。物理内存为 3GB 的时候使用 /3GB 开关,大于等于 4GB 就使用 /PAE 开关。关于 /3GB 开关的描述请见这里,关于 /PAE 开关的描述请见这里

一个需要开启 /PAE 开关的 boot.ini 的实例类似是这样的:

[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(2)\WINNT
[operating systems]
multi(0)disk(0)rdisk(0)partition(2)\WINNT="Windows Server 2000 Server" /noexecute=optout /fastdetect /PAE
如微软的文章中所说,检查完系统是否支持当前的物理内存后,然后需要启用 SQL Server 的 Address Windowing Extentions(AWE)支持。

要检查 AWE 是否已启用,请从 SQL 查询分析器运行以下脚本:

sp_configure 'show advanced options', 1
go
reconfigure
go
sp_configure 'awe enabled'
go
如果 run_value 设置为 1,则服务器上启用了 AWE。如果不是,请在 SQL 查询分析器中输入:

sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
GO
sp_configure 'awe enabled', 1
RECONFIGURE WITH OVERRIDE
GO
sp_configure 'max server memory', 4096
RECONFIGURE WITH OVERRIDE
GO
请注意,这里的 4096 适用 4GB 物理内存的系统。如果是 6GB,这个数字应改成 1024 * 6,其他情况依此类推。

值得特别说明的是,微软的原文介绍使用 RECONFIGURE 命令,而我将之改为强制更新的 RECONFIGURE WITH OVERRIDE 命令。其最终效果是一样的,只不过有些情况下 RECONFIGURE 无法完成工作。

到此为止,理论上 SQL Server 应该可以支持 2GB 以上的物理内存了。但某种情况下,依然不行。为何?我们再来看微软的一篇文章

这里说到这样一个问题:启用了 AWE 支持,但单个 SQL Server 2000 实例还是只能使用计算机上最多 50% 的物理内存。

很不幸地,这个问题被我遇到了。经过一番折腾后,服务器的内存使用量还是在 1.75GB 左右徘徊。这个属于 SQL Server 早期版本中的一个漏洞,该问题只发生在具有超过 2 GB RAM 的计算机上运行于基于 x86 或基于 x64 的计算机上的 32 位版本的 SQL Server 2000 Service Pack 4 中。要查看此现象,请检查系统监视器中的“SQL Server:内存管理器 / 总的服务器内存(KB)”计数器。在运行 SQL Server Service Pack 3(SP3)的计算机上,该值最大可以为计算机上的物理内存量。在运行 SQL Server SP4 的计算机上,该值永远不会超过物理内存的 50%。

下载一个 8MB 的补丁,打了就好。

实践证明,现在的内存使用量已经达到了我们 BT 的要求了:

这样一番折腾之后,任务管理器可能会变得无法准确提供内存使用信息,原因请见这里

最后补充,无论是打开 /3GB 或 /PAE 开关,还是开启 SQL Server 的 AWE 支持,还是打 for SQL Server SP4 的修复补丁,系统必须重启才能生效。