0

我有一个具有以下参数的服务器:

OS: Ubuntu 18.04.4 LTS x86_64
Kernel: 4.15.0-112-generic
CPU: Intel Xeon Silver 4214 (48 Cores) @ 2.201GHz
Memory: 96Gb
SSD SAMSUNG MZQLB960HAJR-00007 894.3Gb x 2

随着安装5.5.5-10.4.12-MariaDB-1:10.4.12+maria~bionic。我有一个 PHP 编写的项目,其中有相当多的数据库查询(每秒约 400-500 次选择 + 每秒约 200-300 次更新)。问题是:在大量用户活动期间数据库相当慢,但在其他任何时候都可以。我的my.cfg文件如下:

# this is read by the standalone daemon and embedded servers
[server]

# this is only for the mysqld standalone daemon
[mysqld]

#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
skip-name-resolve
max_connections = 1000000
bind-address = 0.0.0.0

#
# * Fine Tuning
#
key_buffer_size = 96M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 32

# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover         = BACKUP

lock_wait_timeout = 10
interactive_timeout = 10
wait_timeout = 3

#
# * Query Cache Configuration
#
query_cache_type = 0
query_cache_limit = 0
query_cache_size = 0
open-files-limit = 320000
thread_cache_size = 64

#
# * Logging and Replication
#
log_error = /var/log/mysql/error.log
expire_logs_days = 10
max_binlog_size = 100M

#
# * InnoDB
#

innodb_buffer_pool_size = 10000M
innodb_buffer_pool_instances = 128
max_heap_table_size = 1000M
tmp_table_size = 1000M
sort_buffer_size = 96M
innodb_sort_buffer_size = 96M
read_buffer_size = 96M

#
# * Character sets
#
character-set-server  = utf8mb4
collation-server      = utf8mb4_general_ci


# this is only for embedded server
[embedded]

[mariadb]
max_statement_time = 15
thread_handling = pool-of-threads
thread_pool_size = 48

最近我进行了更改thread_handling = pool-of-threads,并且wait_timeout = 3:它提高了性能,但总体上并没有解决问题。对于如何加快速度或消除一些“瓶颈”的任何想法,我将不胜感激。

更新:

使用 InnoDB,而不是 MyISAM

已经是这样了。

打开慢日志以查找最慢的查询。

好吧,我所有的 SELECT 只调用一个表(约 50 万条记录,没有 JOIN 和/或子查询),而且大多数都有 LIMIT 1,所以数据量不大。

让我们看看 SHOW CREATE TABLE。

好的,这是SHOW CREATE TABLE这个主表:

CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `order_created_datetime` timestamp NULL DEFAULT current_timestamp(),
  `order_updated_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE current_timestamp(),
  `order_last_perform_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  `order_category_id` tinyint(4) DEFAULT NULL,
  `order_url` text CHARACTER SET utf8 DEFAULT NULL,
  `order_social_shortcode` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
  `order_social_id` varchar(128) DEFAULT NULL,
  `order_title` text DEFAULT NULL,
  `order_preview_pic` text DEFAULT NULL,
  `order_custom_data` text DEFAULT NULL,
  `order_price_usd` decimal(13,6) DEFAULT 0.000000,
  `order_daily_limit` int(11) DEFAULT 0,
  `order_hourly_limit` int(11) DEFAULT 0,
  `order_minute_limit` int(11) DEFAULT 0,
  `order_overall_limit` int(11) DEFAULT 0,
  `order_initial_social_counter` int(11) DEFAULT 0,
  `order_daily_counter` int(11) DEFAULT 0,
  `order_hourly_counter` int(11) DEFAULT 0,
  `order_minute_counter` int(11) DEFAULT 0,
  `order_overall_counter` int(11) DEFAULT 0,
  `order_allowed_countries` text CHARACTER SET utf8 DEFAULT NULL,
  `order_forbidden_countries` text CHARACTER SET utf8 DEFAULT NULL,
  `order_api` tinyint(4) DEFAULT 0,
  `order_reported` tinyint(4) DEFAULT 0,
  `order_active` tinyint(4) DEFAULT 1,
  `order_deleted` tinyint(4) DEFAULT 0,
  `order_deleted_datetime` timestamp NULL DEFAULT '0000-00-00 00:00:00',
  `order_deleted_user_id` int(11) DEFAULT NULL,
  `users_log_actions` longtext CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  `users_log_hidden` longtext CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  KEY `index_user_id` (`user_id`) USING BTREE,
  KEY `index_order_category_id` (`order_category_id`) USING BTREE,
  KEY `index_order_deleted` (`order_deleted`) USING BTREE,
  KEY `index_order_active` (`order_active`) USING BTREE,
  KEY `index_order_social_id` (`order_social_id`) USING BTREE,
  KEY `index_users_log_actions` (`users_log_actions`(1024)) USING BTREE,
  KEY `index_users_log_hidden` (`users_log_hidden`(1024)) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=461811 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC

innodb_buffer_pool_size 可能太小——你有多少数据?MariaDB 有多少 RAM 可用?

好吧,MariaDB 在独立服务器上运行,没有任何其他软件(PHP、Apache 等)。所以我在这台服务器上有 96Gb RAM,所有这些都可以被 MariaDB 使用。

innodb_buffer_pool_instances 太大;应该是 - buffer_pool_size/1G

你能澄清一下吗?在我的情况下,它应该是 buffer_pool_size/96Gb,或者?我认为buffer_pool_size在我的配置中有它的默认值。

如果 innodb_flush_log_at_trx_commit 的值是多少?

是的1,但我试过2没有结果。

4

1 回答 1

0

由于您使用的是 innodb,因此需要在第一次调整一些 innodb 参数。

innodb_buffer_pool_size太小,因为您有 96 GB 的 RAM。可以给这个变量至少 50% 并减少innodb_buffer_pool_instances

如果您能承受 1-2 秒的数据丢失,则将innodb_flush_log_at_trx_commit的值设置为 2。

max_allowed_pa​​cket设置为 256 M

将max_connections减少到 1000

tmp_table_size设置为 256M

sql_binloginnodb_doublewrite设置为 0

注意:SELECT (@@key_buffer_size + @@query_cache_size + @@innodb_buffer_pool_size + @@innodb_log_buffer_size + @@max_connections * (@@read_buffer_size + @@read_rnd_buffer_size + @@sort_buffer_size + @@join_buffer_size + @@binlog_cache_size + @@thread_stack + @ @tmp_table_size )) / (1024 * 1024 * 1024) AS MAX_MEMORY_GB; 应小于总 RAM 的 80%。

于 2020-09-16T12:53:37.113 回答