启动参数
| 参数名 | 参数描述 | 默认值 | 建议值 | 分析 |
|---|---|---|---|---|
| memory_limit | OBServer能使用的物理内存,默认为0表示使用全部物理机内存的一个比例(默认80%) | 0 | 当单机起多个OBServer的时候,多个OBServer的使用内存之和要小于物理机总内存的90% | |
| memory_limit_percentage | OBServer使用物理机内存的比例,默认值80(表示80%),范围是[10,90) | 80 | 当单机起多个OBServer的时候,多个OBServer的使用内存之和要小于物理机总内存的90% | |
| datafile_size | OBServer实例的数据文件(block_file)大小 | 0 | 当数据文件和日志文件共用一个文件系统目录时,需要先预留日志文件的空间(日志文件需要空间在内存3-4倍左右)。 | |
| datafile_disk_percentage | OBServer实例的数据文件(block_file)大小占所在文件系统目录的比例 | 0 | 当数据文件和日志文件共用一个文件系统目录时,需要先预留日志文件的空间(日志文件需要空间在内存3-4倍左右)。 | |
| config_additional_dir | config配置文件的冗余目录 | config配置文件默认在/home/admin/etc/下,为了避免丢失,建议再配置两个独立文件系统的目录,以分号隔开。 | ||
| rootservice_list | 总控服务的成员列表 | 如果手动安装OB,需要指定这个总控服务成员列表,一般就是集群最早的三个节点。格式:192.168.0.100:2882:2881;192.168.0.101:2882:2881;192.168.0.103:2882:2881 | ||
| obconfig_url | 获取总控服务地址的WEB API | 如果有OCP安装,OCP会提供API并自动设置这个参数为OCP的API,格式是:http://11.***.***.83:8088/services?Action=ObRootServiceInfo&ObRegion=obdemo。如果没有OCP安装,可以手动模拟一个WEB API,在启动的时候指定这个API,格式是: http://11.***.***.83:8080/oceanbase_obconfig/obdemo。或者先用rootservice_list启动集群成功,后再指定这个参数也行。 | ||
问题诊断相关参数
| 参数名 | 参数描述 | 默认值 | 建议值 | 分析 |
|---|---|---|---|---|
| max_syslog_file_count | 设置observer.log.*和 observer.wf.log.*的文件个数。 | 100 | 如果为0,则不自动删除observer.log,每个log最大256MB,然后滚动生成。有可能会把所在文件系统目录空间打满,所以建议还是设置。 | |
| enable_syslog_recycle | 设置observer.log.*和 observer.wf.log.*循环利用。个数由参数max_syslog_file_count确定 | false | 跟参数max_syslog_file_count搭配使用。如果没有OCP,建议设置为true;否则,建议为False。OCP会自动清理运行日志。 | |
| syslog_level | 设置运行日志的日志level,有DEBUG,TRACE,INFO,WARN,USER_ERROR,ERROR六个级别 | INFO | OBServer运行日志生成量很大,结合所在目录空间大小和实际问题严重程度设置。目前客户还不大可能通过运行日志直接定位到原因,通常是把相关运行日志发送给OB支持人员定位。所以当有问题时,需要尽可能多的保留运行日志。 | |
| trace_log_slow_query_watermark | 在OBServer运行日志里打印执行时间超过这个值的SQL运行信息。 | 2s | 根据实际SQL排查需要指定。不要设置的太小,否则运行日志会打印很多慢查SQL。从最大时间往下逐步设置观察。定位方法:fgrep '[slow query]' observer.log.*。 | |
| enable_sql_audit | 开启或关闭SQL审计功能。 | True | 内部视图gv$sql_audit会记录所有租户的SQL运行日志。视图的内容是保存在内存里,内存大小有参数 sql_audit_memory_limit限制,记录数大小有参数 sql_audit_queue_size限制。当捕获到问题SQL后,为防止视图内容被后续SQL覆盖,可以临时关闭这个参数。 | |
| sql_audit_memory_limit | SQL审计视图gv$sql_audit所占用的最大内存大小。 | 3G | 10G | 如果QPS非常高,并且OBServer内存富余的情况下,可以调大这个参数到10G。 |
| sql_audit_queue_size | SQL审计视图gv$sql_audit的记录数最大大小。 | 10000000 | 如果QPS非常高,可以调大这个参数。 | |
冻结合并转储限速相关参数
No memory or over tenant memory错误等。所以针对不同的写入压力,需要调整冻结合并转储限速相关参数。
| 参数名 | 参数描述 | 默认值 | 建议值 | 分析 |
|---|---|---|---|---|
| memstore_limit_percentage | memstore增量内存占OBServer的内存比例。 | 50 | ||
| freeze_trigger_percentage | memstore内存已使用比例超过这个阈值时会触发minor freeze事件和转储事件。 | 70 | 如果写入压力很大,对内存消耗速度很快的话,需要降低这个阈值,已尽可能的触发转储释放内存。转储对资源消耗不大,对性能影响很小。 | |
| minor_freeze_times | OBServer发起minor freeze事件的次数上限,超过这个阈值后,就会用 major freeze代替 minor freeze,然后这个 minor freeze使用次数又从0开始。 | 10 | 100 | 如果写入压力很大,对内存消耗速度很快的话,需要提高这个阈值,已尽可能推迟major freeze的发生到业务低峰期。后者会触发合并,释放内存,会耗费OBServer一定资源。 |
| enable_merge_by_turn | OBServer合并时是否按Zone依次发起合并。如果不是,则所有Zone同时发起合并。 | False | 合并对性能有一定影响,轮转(依次)合并可以降低这个影响范围,不过轮转期间会发起分区切主,分区上当时如果有大事务会出现中断回滚。 | |
| major_freeze_duty_time | OBServer每天默认触发major freeze事件即合并的时间。 | 02:00 | 建议设置在业务低峰期。 | |
| write_throttling_maximum_duration | OBServer限速目标,预估限速后增量内存还可以持续写入的时间。 | 30m | 这个根据实际写入对内存消耗速度和转储释放内存速度综合确定。 | |
| write_throttling_trigger_percentage | 当增量内存已使用比例到达这个阈值后,即刻开启限速逻辑。 | 85 | 这个根据实际写入对内存消耗速度和转储释放内存速度综合确定。设置的太低,限速太早;设置的太高,限速太晚。 | |
性能调优参数
_开头的参数)。
| 参数名 | 参数描述 | 默认值 | 建议值 | 分析 |
|---|---|---|---|---|
| large_query_threshold | OBServer的大查询执行时间标准。 | 10s | SQL执行时间超过这个值(ms)就被判定为大查询,会使用单独的执行队列。为了避免个别大查询长期占用SQL执行队列导致小而块的查询饿死,OBServer设计了单独的大查询执行队列。根据实际SQL平均执行时间确定。 | |
| large_query_worker_percentage | OBServer大查询执行队列的cpu worker线程数量比例 | 30 | 如果期望大查询尽可能被满足,可以调高这个比例;反之调低这个比例。 | |
| enable_sql_operator_dump | 允许SQL层的排序/hash连接/窗口函数等中间结果dump到磁盘。 | True | True | |
| __temporary_file_io_area_size | 隐含参数,SQL中间结果写入到磁盘上文件大小限制。 | '20G' | ||
| _ob_clog_timeout_to_force_switch_leader | 当clog同步被阻塞的时候,等待时间超过阈值后就回收leader。 | 0s | 设置0s就无限等待。 | |
| _ob_replay_memory_limit | clog回放时最多使用的内存。 | '500M' | '10G' | |
| _ob_clog_disk_buffer_cnt | clog disk buffer cnt. Range: [1, 4000] | 1024 | clog内部参数,减少内存争抢的概率。 | |
| _ob_btree_retire_limit | the retire station batch limit. Range: [16,65536] | 2048 | clog内部参数,减少内存释放时发生锁等待的概率。 | |
| _ob_stat_refresh_timeout | the time to refresh stat cache before it is terminated. Range: [1ms,+∞) | '100s' | 减少内部刷新发生超时的概率。 | |
| memory_chunk_cache_size | the maximum size of memory cached by memory chunk cache. Range: [32M,] | '300G' | 减少OS回收OB内存的概率。 | |
| election_blacklist_interval | If leader_revoke, this replica cannot be elected to leader in election_blacklist_intervalThe default value is 1800s. Range:[0s, 24h] | 1800 | 0 | |
| _ob_trans_rpc_timeout | transaction rpc timeout(s).transaction rpc timeout(s). Range: [0s, 3600s] | '10s' | 调大节点间RPC请求超时时间,减少RPC超时事件。 | |
| enable_auto_leader_switch | specifies whether partition leadership auto-switch is turned on. Value: True:turned on; False: turned off | True | False | 是否开启自动切主,影响负载均衡策略,不影响高可用。当分区分布均衡后就关闭这个参数,避免压测过程中发生负载均衡事件(会有分区迁移和切主)。 |
| rpc_connect_error_retry_times | retry times if rpc connect error, to be removed | 0 | 10 | 调大节点间RPC超时后的重试次数。 |
set @@global.ob_sql_work_area_percentage = 30; -- 定义租户的SQL层可使用的内存空间占比
set @@global.parallel_max_servers=900; -- 提高px可同时并发的线程数上限
set @@global.parallel_servers_target=900; -- 提高px并行度
set @@global.recyclebin='OFF'; -- 关闭回收站
负载均衡参数
| 参数名 | 参数描述 | 默认值 | 建议值 | 分析 |
|---|---|---|---|---|
| enable_rebalance | 是否开启负载均衡机制。 | True | 根据实际情况考虑。 | |
| enable_auto_leader_switch | 是否自动切主。 | True | 如果关闭,则负载均衡机制也不会生效。 | |
| data_copy_concurrency | OB集群里并行数据复制任务最大任务数 | 40 | 控制集群节点间分区迁移力度。 | |
| server_data_copy_out_concurrency | 该OBServer节点分区复制任务流出的最大任务数。 | 10 | 控制单个节点分区迁移数据读出力度。 | |
| server_data_copy_in_concurrency | 该OBServer节点分区复制任务流入的最大任务数。 | 10 | 控制单个节点分区迁移数据写入力度。 | |
| sys_bkgd_net_percentage | sys后台线程使用网络流量比例上限 | 60 | 这个参数比例过高可能导致大部分网卡流量被后台任务(如分区迁移时复制分区数据)占满,可能间接影响业务SQL性能。或者因为分区复制力度太大,间接导致节点磁盘负载过高。 | |
| enable_rereplication | 是否开启副本复制 | True | 特殊变更期间可以关闭这个。关闭后如果副本数目不足,不会自动补齐副本。 |
参数修改脚本
#!/usr/bin/env python
# coding=utf-8
import sys,os,time
import yaml
import MySQLdb
from getopt import getopt, GetoptError
class Option():
OB_CONFIG = """{
ob_cluster_int_params:{
clog_disk_usage_limit_percentage: 90,
data_disk_usage_limit_percentage: 90,
minor_freeze_times: 3,
cpu_reserved: 2,
memory_limit_percentage: 90,
memstore_limit_percentage: 70,
freeze_trigger_percentage: 50,
max_syslog_file_count: 100,
zone_merge_concurrency: 0,
merge_thread_count: 0,
global_write_halt_residual_memory: 30,
global_major_freeze_residual_memory: 40,
minor_merge_concurrency: 0,
large_query_worker_percentage: 30,
sys_bkgd_net_percentage: 60,
user_iort_up_percentage: 100,
sys_bkgd_io_high_percentage: 90,
sys_bkgd_io_low_percentage: 0
},
ob_cluster_str_params:{
autoinc_cache_refresh_interval: 72000s,
syslog_level: INFO,
enable_syslog_recycle: true,
enable_merge_by_turn: false,
major_freeze_duty_time: "02:00",
merger_warm_up_duration_time: 300s,
minor_warm_up_duration_time: 300s,
large_query_threshold: 500ms,
trx_force_kill_threshold: 100ms,
zone_merge_timeout: 3h,
trx_try_wait_lock_timeout: 0ms,
trace_log_slow_query_watermark: 100ms,
syslog_io_bandwidth_limit: 30MB,
default_compress_func: "zstd_1.0"
}
}
"""
hosts = os.getenv('OB_SERVER_IP_LIST', '127.1')
host = hosts.split(',')[0]
port = int(os.getenv('OB_SERVER_SQL_PORT', 2881))
user = 'root@sys'
password = os.getenv('OB_SERVER_PASSWD', '')
database = 'oceanbase'
params = yaml.load(OB_CONFIG)
class ObConn():
def __init__(self):
self.conn = MySQLdb.connect(host=Option.host, port=Option.port, user=Option.user, passwd=Option.password, db=Option.database)
def run_sql(self, sql_str):
try:
cursor = self.conn.cursor(MySQLdb.cursors.DictCursor)
rows_count = cursor.execute(sql_str)
except MySQLdb.Error as err:
print(err)
sys.exit(1)
else:
if rows_count > 0:
rows = cursor.fetchall()
cursor.close()
return rows
else:
cursor.close()
return None
def close(self):
self.conn.close()
def parse_arg():
try:
opts, args = getopt(sys.argv[1:], "h:P:u:p:", ["help", "host=", "port=", "password="])
except GetoptError as err:
print str(err)
print('Usage: python obparam.py [-h|--host=HOST] [-P|--port=PORT] [-u|--user=USER] [-p|--password=PASSWORD]')
sys.exit(1)
for o, v in opts:
if o == "--help":
usage()
sys.exit(1)
elif o in ("-h", "--host"):
Option.host = v
elif o in ("-P", "--port"):
Option.port = int(v)
elif o in ("-p", "--password"):
Option.password = v
elif o in ("-u", "--user"):
Option.user = v
else:
assert False, "unhandled option"
def Main():
parse_arg()
db_conn = ObConn()
for k,v in Option.params['ob_cluster_int_params'].iteritems():
db_conn.run_sql("alter system set {0} = {1}".format(k, int(v)))
print(k, v)
for k,v in Option.params['ob_cluster_str_params'].iteritems():
db_conn.run_sql("alter system set {0} = '{1}'".format(k, v))
print(k, v)
if __name__ == "__main__":
Main()
sudo yum -y install MySQL-python.x86_64 PyYAML.x86_64
推荐阅读
文章转载自数据库技术闲谈,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




