云服务器内容精选

  • GaussDB(for MySQL)实例在空负载下CPU占用说明 GaussDB(for MySQL)实例上包括操作系统进程、mysqld进程、监控进程、增量备份进程等。mysqld进程包含多个线程比如主备通信线程、连接线程、刷新线程等。监控进程负责实时监控实例的状态,增量备份进程负责进行增量数据备份。因此在实例空载情况下,仍然有多个进程和线程在后台持续运行,CPU的占用率不会为0,通常空载时CPU占用率为10%~15%。 父主题: 数据库性能
  • 原因分析 查看监控指标“行锁花费时间”,监控到行锁等待时间较长,说明该系统出现过锁冲突的现象。 监控指标详细内容请参考查看监控指标。 登录实例,执行如下SQL,查看系统当前存在的长事务,以及事务持有的行锁信息。 select trx_mysql_thread_id, trx_id, trx_state, trx_started, trx_tables_locked, trx_rows_locked, trx_isolation_level, trx_query, trx_operation_state from information_schema.innodb_trx order by trx_started; information_schema.innodb_trx表包含了当前innodb内部正在运行的事务信息。 trx_started:表示事务的开始时间,用来判断当前事务是否是长事务,当前时间减去开始时间就是事务的执行时间。 trx_state :表示当前事务的状态,取值如下: RUNNING:运行。 LOCK WAIT:等待锁。 如果事务当前的状态是LOCK WAIT,即表示事务持有行锁。 ROLLING BACK:正在回滚。 COMMITTING:正在提交。
  • 减少或避免表膨胀 开启autovacuum。 提高系统的IO能力。 调整触发阈值,让触发阈值和记录数匹配。 增加autovacuum_max_workers和autovacuum_work_mem,同时增加系统内存。 IO性能较好的系统,关闭autovacuum_vacuum_cost_delay。 设计应用程序时,避免使用大批量的更新、删除操作,可以切分为多个事务进行。 应用程序设计时,尽量避免下列操作: 打开游标后不关闭。 在不必要的场景使用repeatable read或serializable事务隔离级别。 对大的数据库执行gs_dump进行逻辑备份(隐式repeatable read隔离级别的全库备份)。 长时间不关闭申请了事务号的事务(增、删、改等DDL操作的SQL)。
  • 相关空间回收参数说明 autovacuum = on 控制数据库自动清理进程(autovacuum)的启动。自动清理进程运行的前提是将track_counts设置为on。 log_autovacuum_min_duration = 0 当自动清理的执行时间大于或者等于某个特定的值时,向服务器日志中记录自动清理执行的每一步操作。设置此选项有助于追踪自动清理的行为。 autovacuum_max_workers = 10 设置能同时运行的自动清理线程的最大数量。 autovacuum_naptime = 1 设置两次自动清理操作的时间间隔。 autovacuum_vacuum_cost_delay = 0 设置在自动VACUUM操作里使用的开销延迟数值。 更多关于空间回收参数说明,参见自动清理。
  • 表膨胀的原因 未开启autovacuum GaussDB(DWS)提供自动执行VACUUM和ANALYZE命令的系统自动清理进程(autovacuum),用于回收被标识为删除状态的记录空间,并更新表的统计数据。 用户未开启autovacuum的同时又没有合理的自定义vacuum调度,导致表的脏数据没有及时回收,新的数据又不断插入或更新,膨胀是必然的。 资源回收不及时 开启了autovacuum,但是各种原因导致回收不及时,并且新的数据又不断产生,从而导致膨胀。回收不及时有以下原因: IO性能差 当数据库非常繁忙时,如果IO性能较差,会导致回收脏数据变慢,从而导致表膨胀。 这种情况一般出现在占用数据库内存较大的表上,并且这些表正在执行整表vacuum,因此产生大量IO,导致表自身或其他表膨胀。 autovacuum触发较迟 触发autovacuum操作的阈值设置过高,大量表上被删除、插入或更新的记录数没有及时处理,导致表膨胀。 autovacuum线程繁忙 所有自动清理线程繁忙,某些表产生的脏数据超过阈值,但是在此期间没有autovacuum线程可以处理脏数据回收的事情,可能发生表膨胀。 如果数据库的表很多,而且都比较大,那么当需要vacuum的表超过了配置autovacuum_max_workers的数量,这些表就要等待空闲的autovacuum线程。这个阶段就容易出现表的膨胀。 数据库中存在长SQL或带XID的长事务 当DWS数据库中存在未结束的SQL语句或者未结束的持有事务ID的事务,在此SQL执行时间范围内或在此事务过程中产生的脏数据无法回收,导致数据库膨胀。 开启了autovacuum_vacuum_cost_delay 在开启了autovacuum_vacuum_cost_delay后,会使用基于成本的脏数据回收策略,可以有利于降低VACUUM带来的IO影响,但是对于IO性能高的系统,开启autovacuum_vacuum_cost_delay反而会使得垃圾回收的时间变长。 autovacuum_naptime设置间隔时间过长 批量删除或更新大表 例如对于一个10GB的表,一条SQL或一个事务中删除或更新9GB的数据,这9GB的数据必须在事务结束后才能进行脏数据回收,无形中增加了膨胀的可能。
  • 共享配额 共享配额:关联在当前资源池的用户在执行作业时可以使用的CPU时间比例。 共享配额有两层含义: 共享:CPU是所有控制组共享的,其他控制组能够使用空闲的CPU资源。 配额:业务繁忙、CPU满负载情况下,控制组之间按照配额比例进行CPU抢占。 共享配额基于cpu.shares实现,只有在CPU满负载情况下生效,因此在CPU空闲情况下并不能保证控制组能够抢占到配额比例的CPU资源。CPU空闲并不能理解为没有CPU资源争抢,控制组内任务可以任意使用CPU。虽然CPU平均使用率可能不高,但是某个特定时刻还是可能存在CPU资源争抢的。 例如:10个CPU上运行10个作业,每个CPU上运行1个作业,这种情况下各作业在任意时刻请求CPU都可以瞬间得到响应,作业之间没有任何CPU资源的争抢;但假如10个CPU上运行20个作业,因为作业不会一直占用CPU,在某些时间可能等待IO、网络等,因此CPU使用率可能并不高,此时CPU资源看似空闲,但是在某个时刻可能出现2~N作业同时请求一个CPU的情况出现,即会导致CPU资源争抢,影响作业性能。
  • CPU资源管控概述 在不同的业务场景中,对数据库的系统资源(CPU资源、内存资源、IO资源和存储资源)进行合理的分配,保证执行查询时有充足的系统资源,确保查询性能,可以维持业务稳定性。 GaussDB(DWS)的资源管理功能支持用户根据自身业务将资源按需划分成不同的资源池,不同资源池之间资源互相隔离。再通过关联数据库用户将其关联至不同的资源池,用户SQL查询时将根据“用户-资源池”的关联关系将查询转至资源池中执行。通过指定资源池上可并行运行的查询数、单查询内存上限以及资源池可使用的内存和CPU资源,从而实现对不同业务之间的资源限制和隔离,满足数据库混合负载需求。 GaussDB(DWS)主要利用cgroup(control group,控制组)进行CPU资源管控,涉及CPU、cpuacct、cpuset子系统。CPU共享配额管控基于CPU子系统的cpu.shares实现,该配置方法的好处是:OS CPU没有占满的情况下,不触发CPU管控;CPU专属限额管控基于cpuset实现;cpuacct子系统主要用于CPU资源使用的监控。 在DWS管理控制台使用资源管理配置功能创建资源池时,根据业务需要对CPU资源管理的“共享配额”和“专属配额”进行配置。
  • 专属限额 专属限额:限定资源池中数据库用户在执行作业时可使用的最大CPU核数占总核数的百分比。 专属限额有两层含义: 专属:CPU是某个控制组专属的,其他控制组不能使用空闲的CPU资源。 限额:只能使用限额配置的CPU资源,其他控制组空闲的CPU资源,也不能抢占。 专属限额基于cpuset.cpu实现,通过合理的限额设置可以实现控制组之间CPU资源的绝对隔离,各控制组间任务互不影响。但因为CPU的绝对隔离,因此在控制组空闲时就会导致CPU资源的极大浪费,因此限额设置不能太大。从作业性能来看并不是限额越大越好。 例如:10个作业运行在10个CPU上,CPU平均使用率5%左右;10个作业运行在5个CPU上,CPU平均使用率10%左右。通过上面共享配额的分析可知:虽然10个作业运行在5个CPU上CPU使用率很低,看似空闲,但是相对10个作业运行在10个CPU上还是存在某种程度的CPU资源争抢,因此10个作业运行在10个CPU上性能要好于运行在5个CPU上。但也不是越多越好,10个作业运行在20个CPU上,在任意一个时刻,总会至少10个CPU是空闲的,因此理论上10个作业运行在20个CPU上并不会比运行在10个CPU上性能更好。对于并发为N的控制组,分配cpus小于N的情况下,CPU越多作业性能越好;但是当分配CPUS大于N的情况下,性能就不会有任何提升了。
  • CPU资源管理应用场景 CPU共享配额和专属限额的管控方式各有优劣,共享配额能够实现CPU资源的充分利用,但是各控制组之间资源隔离不彻底,可能影响查询性能;专属限额的管控方式可以实现CPU资源的绝对隔离,但是在CPU资源空闲时会造成CPU资源的浪费。相对专属限额来说,共享配额拥有更高的CPU使用率和更高的整体作业吞吐量;相对共享配额来说,专属限额CPU隔离彻底,更满足性能敏感用户的使用诉求。 数据库系统中运行多种类型作业出现CPU争抢时,可根据不同场景,选择不同的CPU资源管控方式: 场景一:实现CPU资源的充分利用,不关注单一类型作业的性能,主要关注CPU整体吞吐量。 应用建议:不建议进行用户之间的CPU隔离管控,无论哪一种CPU管控都会对CPU整体使用率产生影响。 场景二:允许一定程度的CPU资源争抢和性能损耗,在CPU空闲情况下实现CPU资源充分利用,在CPU满负载情况下需要各业务类型按比例使用CPU。 应用建议:可以采用基于cpu.shares的共享配额管控方式,在实现满负载CPU隔离管控前提下,尽量提高CPU整体使用率。 场景三:部分作业对性能敏感,允许CPU资源的浪费。 应用建议:可以采用基于cpuset.cpu的专属限额管控方式,实现不同类型作业之间的CPU绝对隔离。
  • 原因分析 查看监控指标“行锁花费时间”,监控到行锁等待时间较长,说明该系统出现过锁冲突的现象。 监控指标详细内容请参考查看监控指标。 登录实例,执行如下SQL,查看系统当前存在的长事务,以及事务持有的行锁信息。 select trx_mysql_thread_id, trx_id, trx_state, trx_started, trx_tables_locked, trx_rows_locked, trx_isolation_level, trx_query, trx_operation_state from information_schema.innodb_trx order by trx_started; information_schema.innodb_trx表包含了当前innodb内部正在运行的事务信息。 trx_started:表示事务的开始时间,用来判断当前事务是否是长事务,当前时间减去开始时间就是事务的执行时间。 trx_state :表示当前事务的状态,取值如下: RUNNING:运行。 LOCK WAIT:等待锁。 如果事务当前的状态是LOCK WAIT,即表示事务持有行锁。 ROLLING BACK:正在回滚。 COMMITTING:正在提交。