OceanBase运维驾驶基础
传统运维学习OceanBase多少会因为不熟悉新事物有些担心,然而换OceanBase就跟换一辆高级车一样区别不会太多。由于大部分人还没接触过OceanBase,这里介绍OceanBase运维还有点早。不如先分享一下如果要安装OceanBase需要具备哪些经验。对于老司机而言,下面的内容都会显得很浅显,可以直接拉到最后。
数据库服务器
对于主要使用IOE
架构的企业,估计很少用普通商用服务器去部署数据库,所以DBA
或者运维都很少去想一个数据库服务器要做哪些事情。所以当发现要把数据库搬到普通服务器上时,会有非常多的担心。如性能行不行、可靠性高不高、怎么做高可用、出事了谁担责任。这种担心也很正常,在早期阿里巴巴DBA探索在普通服务器上部署ORACLE时,也是内部争论很多,有很多担心。从这篇旧文《ORACLE Fusion-io最佳实践 http://www.hellodb.net/2011/02/oracle-fusion-io.html》可以看出。
选用商用服务器后,性能主要取决于CPU和IO。这里稍微深入的分析一下。
CPU
普通服务器的CPU
是x86
架构架构.其单HZ处理能力已经超过IBM的Power序列。不过Power序列的内存访问使用SMP
结构,所有CPU访问内存速度都一致,x86
服务器访问内存采用NUMA
结构,CPU和内存的节点一一对应,跨节点访问性能会有下降(有点分布式存储的感觉),并且还有不同内存节点间同步成本。所以随着CPU增长,x86
的线性增长能力可能不如Power
序列。当然单纯比较CPU意义也不大,还要综合稳定性看。不过使用x86
服务器做数据库服务器,一个经验就是关闭NUMA
。NUMA
关闭方法也很简单,在/etc/grub.conf
的kernel
一行后添加了numa=off
,重启服务器就生效。所以,如果要准备OceanBase数据库服务器,也请先关闭NUMA
。
此外对于CPU
还有描述也需要了解一下。物理CPU指真实的CPU硬件,通常说的几路就是指这个个数,Linux下用不同Physical ID
区分。核心数(Core
)是物理CPU的内部划分。Intel的CPU
支持超线程技术,每个Core
可以变成两个逻辑CPU
。
# 查看物理CPU个数
cat /proc/cpuinfo | grep 'physical id' | sort
| uniq |wc -l
# 查看核心个数
cat /proc/cpuinfo | grep 'core id' | sort
| uniq |wc -l
# 查看逻辑CPU个数
cat /proc/cpuinfo | grep 'processor' |sort
|
wc -l
#lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 24
On-line CPU(s) list: 0-23
Thread(s) per core: 2
Core(s) per soc
ket: 6
Socket(s): 2
NUMA node(s): 1
......
日常交流中我们说的CPU个数多是指逻辑CPU
个数。OceanBase进程启动后,会获取服务器的逻辑CPU
个数,扣除2个给OS,其他都声称是自己的。OceanBase的测试环境建议CPU
个数不要低于32个。
内存
linux的内存页大小是4K
,如今内存都很大,256G也不算什么,为了管理这么多内存页,OS的页目录也会非常大。所以Linux从内核2.6版本后支持一种大页技术,页大小为2M
。后来RHEL 6
又引入透明大页技术,前者就叫传统大页技术。二者区别是传统大页管理是预分配、透明大页管理是动态分配。使用透明大页时,可能在分配失败时内核会尝试直接回收和压缩其他内存导致sys
飙高,系统性能可能出现大幅抖动甚至重启。ORACLE的安装文档就建议使用传统大页,关闭透明大页。OceanBase也是同理。
#在线关掉方法:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
存储
存储常常是数据库的性能瓶颈,也是运维最大的担忧。商用服务器当然也支持连接FC存储。不过如今这早已不是唯一选择。如今使用SSD方案的IO性能已经可以远远超过存储。SSD的类型很多,早期使用SSD的时候会有一个擦写次数的限制(寿命问题)。数据库IO通常有两种类型特点,一是随机IO
,一是顺序IO
。ORACLE数据库的数据读写多是随机IO
比较多,所以对SSD
寿命有要求。OceanBase读写有随机IO
,不过次数相对来说很少(因为OceanBase使用LSM模型,写首先是尽可能的缓存在内存里,不及时落盘)。此外就是密集的大IO,可能也有很多顺序IO。总体来说OceanBase对SSD
寿命非常友好。
SSD
的存储流程是数据经过设备物理接口,然后是逻辑协议转换为指令协议。这其中物理接口有SATA
、PCIE
的区别,逻辑协议有AHCI
和NVME
之分。NVME
相对于AHCI
具有低延时、高IOPS
、低功耗等。
物理接口 | 逻辑协议 | 指令协议 |
SATA | AHCI | ATA |
M.2/PCIe | AHCI | ATA |
PCIe/U2 | NVMe | NVMe |
就实际使用体验而言,使用SATA
接口的SSD
,IO
依然很可能是数据库的性能瓶颈,而使用PCIe
接口搭配NVMe
协议的SSD
时,数据库性能瓶颈通常又转移到CPU
了。OceanBase生产环境如果业务对数据库性能要求非常高,建议搭配适量的NVMe
协议的SSD
盘。
Linux操作系统
内核参数设置
Linux的内核参数在/etc/sysctl.conf
里修改。通常数据库软件的原理都会内部使用多线程,使用信号量,并且大量读写文件和网络设备(本质上也是文件)。所以ORACLE数据库的安装里会建议调整相关内核参数,OceanBase也是如此。这些参数都是共性。
vi /etc/sysctl.conf
# for database
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 10000
net.core.rmem_default = 16777216
net.core.wmem_default = 16777216
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.ip_local_port_range = 3500 65535
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_slow_start_after_idle=0
vm.swappiness = 0
kernel.core_pattern = /data/1/core-%e-%p-%t
vm.min_free_kbytes = 2097152
生效命令
sysctl -p
Shell资源限制设置
数据库软件启动时也是在某个Shell
会话下,而Linux默认会限制一个会话打开的资源。如文件句柄数、栈大小等等。这些默认值并不满足数据库软件的需求。也需要修改。
vi /etc/security/limits.conf
* soft nofile 655350
* hard nofile 655350
* soft stack 20480
* hard stack 20480
* soft nproc 655360
* hard nproc 655360
* soft core unlimited
* hard core unlimited
修改完后要退出当前会话再次登录验证
admin$ulimit -a
$ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 385847
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 655360
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 20480
cpu time (seconds, -t) unlimited
max user processes (-u) 655360
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
安全和防火墙设定
SELinux是Linux的一个安全子系统,默认设置对进程访问权限限制很多。想用好SELinux非常麻烦,数据库软件通常都建议直接关闭这个服务。
在线关闭(其实是设置为Permissive)
#命令行下关闭
#setenforce 0
#getenforce
Permissive
永久关闭,修改配置文件,并重启。
vi /etc/selinux/config
SELINUX=disabled
注意这个文件千万不要改错,否则重启后OS会启动失败。需要进入单用户模式修复。
Linux默认安装会启动防火墙,而数据库通常都会有一些监听端口响应用户请求。分布式数据库节点之间也会有通信需求。需要开通相关端口的访问权限。不过大企业运维里,一一去设置服务器的防火墙非常麻烦,一旦设置错误排查定位也不容易,所以都选择直接关闭。服务器的访问安全通过网络在VLAN
级别设置端口访问的白名单和黑名单来保证。
#清理防火墙规则
#iptables -F
#查看防火墙规则
#iptables -nvL
#停用防火墙服务
#systemctl stop filrewalld
#禁用防火墙服务(防止重启后启动)
#systemctl disable firewalld
时间同步
数据库服务器的时间和应用服务器的时间,以及用户生活中的时间应保持同步。企业生产环境都有专用的时间同步服务器(又叫NTP
服务器)。运维需要能排查服务器跟NTP
源的时间差异。
#配置ntp源
vi /etc/ntp.conf
#添加
server 110.75.186.247 iburst minpoll 8 maxpoll 10
#查看同步误差
#ntpq -4p
#查看当前同步进度
$ntpstat
synchronised to NTP server (100.***.3.1) at stratum 3
time correct to within 6 ms
polling server every 64 s
不过对于集群数据库而言,还要看节点之间的时间同步误差。理论上大家都跟NTP
保持同步的话,各个节点之间的时间误差未必很大。
$clockdiff 100.***.152.81
.
host=100.***.152.81 rtt=750(187)ms/0ms delta=0ms/0ms Sat Jul 6 10:08:25 2019
在很多企业的线下环境里,都没有专用的NTP
服务器,当需要时间同步时,可以挑选一台性能相对好的服务器做NTP
服务器
# yum -y install ntpd
# vi /etc/ntp.conf
#删除所有行
#注释restrict default ignore
server 127.127.1.0 # local clock
fudge 127.127.1.0 stratum 10 # 跟本地硬件同步
#当然,我们也可以添加server xxx.xxx.xxx.xxx,让他和其他的time server时间同步。
各个机器配置server
后地址为NTP
源即可。第一次如果通过clockdiff
发现跟NTP
源时间差异很大,可以先用 ntpdate -u NTP源IP
强制同步时间。注意手动同步可能跟自动同步会有冲突:1 Sep 20:09:19 ntpdate[2614]: the NTP socket is in use, exiting
。这个避开同时运行即可。
然后重启 ntpd服务
#systemctl restart ntpd
NTP
同步有个特点,一旦时间相差很大时,同步的时候会一点点缩小差距,目地是为了避免时间跳动范围太大。对于OceanBase集群数据库而言,各个节点的时间误差必须保证在100ms
以内(否则集群的核心选举服务会异常),50ms
以内比较保险,10ms
以内最佳。如果NTP
自动同步服务依然不能保证各个节点时间误差在要求以内,那可以用crontab
每分钟定时同步。快速恢复集群的稳定性比什么都重要。
#crontab -e
* * * * * /sbin/ntpdate -u 100.***.152.81 >> /tmp/ntpdate.log 2>&1
用户设置
新建用户是最简单的操作,用useradd
命令即可。不过很少有人会指定用户的uid
和gid
。这里就提一下,可能在某些情况下涉及到目录的共享时,虽然都是同一个用户但是由于各自的uid
以及gid
不同导致有权限问题。
# groupadd -g 500 admin
# useradd -u 500 -g 500 admin
# groupmod -g 500 admin
# usermod -u 500 -g 500 admin
文件系统设置
所有的关系型数据库都有事务日志(通常说的Redo
),日志的写IO
特点是顺序IO
,数据文件的写IO
特点多是随机IO
。为了性能考虑,最佳实践通常都是建议存放数据文件和事务日志文件的设备文件彼此独立,这样减少彼此的争用。通常性能最好的磁盘会存放事务日志(日志写可能是数据库性能的瓶颈)。
这里有很多种做法。
如果机器盘很多,那么建议2块盘做RAID 1
给OS用,其他的盘分为两部分,分别做RAID 10
或RAID 5
,输出两块物理设备,然后分别格式化为文件系统。
如果机器盘不多时,分开可能难以兼顾OS、数据和日志的空间或性能需求。则可以用LVM
将多块盘(PV
)聚合在一起,然后划分出不同的逻辑设备(LV
),然后再针对性格式化为文件系统,提供给数据和日志使用。
LVM
是卷管理软件,对管理磁盘非常方便,将物理层和业务层彻底隔离,可以很方便给LV
扩容和缩容(而fdisk
分区软件则有扩容不方便问题)。Linux在默认安装的时候,常用LVM管理磁盘。运维需要详细看看分区内容是否合理。特别是作为数据库服务器,手动使用LVM
管理极为重要,一定要尽可能的保证数据目录和日志目录使用的设备尽可能的独立。
还有一种情形,服务器只有两块盘,这个时候还要做RAID
最后只能输出一块设备。这时候不管怎么管理划分,在底层数据文件和日志文件都是共用一个物理设备。除非这个盘是NVME协议的SSD大盘,否则实际性能并不很好。这样的服务器,也并不适合做数据库服务器用。
总结: 以上要求可以作为数据库主机的通用安装模板.
Docker技术
以前安装数据库都是DBA手动一步一步安装,数据库厂商也写了很详尽的安装文档,在安装的过程中学习。当大量数据库使用普通服务器时(指的是MySQL),DBA一台台手动安装可能就比较麻烦,还容易出错。除了操作系统安装自动化配置安装模板外,还有就是用Docker部署。
对于要安装的应用或数据库,首先制作一个docker镜像,将基本的配置、软件包都包含进去,然后写编排任务,在启动docker以后动态的根据配置传递不同的启动参数和执行一些固定的自定义初始化操作。Docker需要掌握一些基本的命令。
首先建议给docker准备一个专用的文件系统用于存放镜像文件,目录名:/docker
。
其次就是安装docker
# 安装docker软件
# yum -y install docker
#启动docker服务
# systemctl start docker
然后就是加载镜像、查看和运维docker。
# 加载镜像
# docker load -i ocp2.tar.gz
# 查看镜像
# docker images
# 查看运行的docker
# docker ps
# 查看所有的docker(包括已停止的)
# docker ps -a
# 启动/停止/重启 某个 docker
# docker start/stop/restart xxxxx(docker标识或名称)
# 删除 docker
# docker rm xxx
# 删除镜像
# docker rmi xxx
# 查看docker运行日志
# docker logs xxx
# 进入docker
# docker exec -it xxxxx(docker标识或名称) bash
# 向docker复制文件
# docker cp filexxx.gz xxxx:~/ # xxxx是docker标识或名称
OceanBase的安装支持手动安装方式和自动安装,自动安装是通过OCP
平台做的。OCP
的安装是使用Antman
产品(原理是Docker)部署,要求有三台物理机。会在每台机器上起3个Docker,分别是OCP
,OBProxy
和OB
。这个OB
是OCP
的元数据库,是运维最重要的数据库,所以建议机器配置不要低于业务数据库主机要求。
运维问题定位
如果问题有明确的报错信息,则根据报错信息定位。
比如说报不能打开文件之类,实际上有成功的也有失败的,则看用户的ulimit
设置里参数是否合理。如果是没有权限打开文件,则看文件所在目录的owner,进程owner
是否正确。如果问题是进程异常退出,则看系统日志/var/log/messages
里是否有OOM之类报错。
如果OB数据库基本的SQL都报超时错误,则先看OB集群的多个节点之前的时间是否同步,NTP服务器是否正常等。
性能问题
有时候主机会表现出性能下降,进而导致数据库出现异常。二者之间的联系并不一定表现的很直接。因此在碰到问题的时候,可以顺便快速的看看主机的性能是否正常。通常只需要看CPU、内存、磁盘、网络就行。这里直接推荐用一个命令(tsar
)就可以看所有的。
CPU性能
CPU用top
命令也可以看。原理相同。通常情况下,数据库很忙的时候,load
会偏高、user
利用率会相对比较高。再从top
命令里看是哪个进程。如果是数据库进程,那基本确认是数据库内部性能问题。如果sys
利用率也相对比较高(如超过20
),则留意OS的异常。如果wait
利用率相对比较高,则看看IO
的性能。
load
的结果里load1
,load5
,load15
分别代表1分钟内,5分钟内,15分钟内平均值。可以看出load
变化趋势。
$tsar --cpu --load -l -i 3
Time -----------------------cpu---------------------- -------------------load-----------------
Time user sys wait hirq sirq util load1 load5 load15 runq plit
07/07/19-15:24:54 25.59 10.62 3.08 0.00 0.42 36.63 13.78 12.99 12.15 5.00 2.8K
07/07/19-15:24:57 25.42 10.63 7.10 0.00 0.42 36.46 13.72 12.99 12.15 10.00 2.8K
07/07/19-15:25:00 25.25 10.11 3.85 0.00 0.40 35.77 13.58 12.97 12.15 3.00 2.8K
07/07/19-15:25:03 29.34 11.31 4.89 0.00 0.48 41.13 13.58 12.97 12.15 7.00 2.8K
07/07/19-15:25:06 24.80 9.93 5.92 0.00 0.36 35.09 13.37 12.94 12.14 25.00 2.8K
^C
MEM性能
Memory主要是关注free
、buffer
、cache
的变化是否正常。通常运行一段时间后数据库主机的内存分布就比较固定了。如有异常变化,还需要结合其他信息判断。
#tsar --mem -l -i 3
Time -----------------------mem----------------------
Time free used buff cach total util
07/07/19-15:31:46 3.0G 31.2G 1.8G 58.2G 94.2G 33.16
07/07/19-15:31:49 3.0G 31.2G 1.8G 58.2G 94.2G 33.13
07/07/19-15:31:52 3.0G 31.2G 1.8G 58.2G 94.2G 33.15
07/07/19-15:31:55 3.0G 31.2G 1.8G 58.2G 94.2G 33.15
^C
IO性能
看IO性能首先要确认当前的磁盘分区、文件系统设置等。通过fdisk
、mount
和df -h
命令查看。找到数据库数据和文件所在的磁盘,使用tsar
观察IO
性能。对于一个磁盘的吞吐能力,响应时间水平应该事先有所了解。
#ll /dev/mapper/ob_vg-ob_data
lrwxrwxrwx 1 root root 7 Jun 12 15:28 /dev/mapper/ob_vg-ob_data -> ../dm-1
#ll /dev/mapper/ob_vg-ob_log
lrwxrwxrwx 1 root root 7 Jun 12 15:28 /dev/mapper/ob_vg-ob_log -> ../dm-0
#tsar --io -I dm-0 -l -i 3
Time ------------------------------------------dm-0------------------------------------------
Time rrqms wrqms rs ws rsecs wsecs rqsize qusize await svctm util
07/07/19-15:38:09 0.00 0.00 0.00 251.67 0.00 5.3K 21.67 2.00 8.89 3.97 99.87
07/07/19-15:38:12 0.00 0.00 0.00 231.67 0.00 4.7K 20.85 2.00 9.08 3.95 91.50
07/07/19-15:38:15 0.00 0.00 0.00 227.33 0.00 1.7K 7.73 1.00 8.71 4.39 99.73
07/07/19-15:38:18 0.00 0.00 0.00 213.33 0.00 1.3K 6.36 1.00 8.31 4.31 92.00
07/07/19-15:38:21 0.00 0.00 0.00 202.33 0.00 1.1K 5.54 1.00 9.09 4.51 91.20
07/07/19-15:38:24 0.00 0.00 0.00 230.67 0.00 1.3K 5.57 1.00 8.34 4.32 99.73
07/07/19-15:38:27 0.00 0.00 0.00 203.33 0.00 1.1K 5.65 1.00 8.65 4.49 91.27
07/07/19-15:38:30 0.00 0.00 0.00 224.67 0.00 1.5K 6.84 1.00 8.34 4.43 99.47
07/07/19-15:38:33 0.00 0.00 0.00 232.33 0.00 3.0K 13.11 2.00 8.61 3.96 92.07
07/07/19-15:38:36 0.00 0.00 0.00 210.67 0.00 1.2K 5.80 1.00 8.27 4.36 91.87
07/07/19-15:38:39 0.00 0.00 0.00 227.33 0.00 1.3K 5.75 1.00 8.16 4.39 99.90
^C
其中IO Util
是个比较复杂的参数。如果是机械盘,这个Util
可以反映出磁盘的繁忙程度,svctm
会在几毫秒以上。如果是SSD
盘,svctm
会在零点几毫秒。关于利用率有个近似公式:利用率U = 吞吐量 * 每次平均服务时间
. 所以SSD盘需要看响应时间(svctm
)、等待时间(await
)等信息综合判断是否到瓶颈。
网络
首先通过ethtool
命令查看网卡的速度。然后通过tsar
命令看网卡实际上传下载速度以及丢包率。如果接近或者超过网卡的能力,则表示网卡此刻接近吞吐量瓶颈。
#ethtool bond0
Settings for bond0:
Supported ports: [ ]
Supported link modes: Not reported
Supported pause frame use: No
Supports auto-negotiation: No
Advertised link modes: Not reported
Advertised pause frame use: No
Advertised auto-negotiation: No
Speed: 2000Mb/s
Duplex: Full
Port: Other
PHYAD: 0
Transceiver: internal
Auto-negotiation: off
Link detected: yes
#tsar --traffic -l -i 3
Time ---------------------traffic--------------------
Time bytin bytout pktin pktout pkterr pktdrp
07/07/19-15:58:24 8.7M 2.3M 9.9K 6.1K 0.00 0.00
07/07/19-15:58:27 9.0M 2.6M 10.0K 6.2K 0.00 0.00
07/07/19-15:58:30 9.7M 2.7M 10.7K 6.5K 0.00 0.00
07/07/19-15:58:33 10.7M 2.6M 11.0K 6.1K 0.00 0.00
07/07/19-15:58:36 8.5M 2.2M 9.5K 5.7K 0.00 0.00
^C
备注:
主机的性能是最容易看最基础的,如果主机在某方面呈现性能瓶颈,数据库的性能和稳定性很可能会受影响。二者之间的联系并不会表现的很直接,需要多观察总结成经验。tsar 更多用法参见《推荐一款淘宝开源的主机性能采集软件——tsar》。
总结
以上大部分说的是用普通服务器作为数据库服务器的一些运维经验。传统业务转型到分布式数据库架构后,普通服务器的规模和运维工作量会增加,因此一些基础的数据库主机安装模板、运维规范以及自动化运维都会应运而生。然而自动化运维产品不是智能化产品,当环境不标准或者异常时,其机制就可能失效,就需要运维介入处理。掌握一些基础的技能是数据库运维安全驾驶的前提。