寻找专用mariadb服务器的正确配置 - 用于巨大的innodb表

问题描述 投票:1回答:6

我一直在一个单独的服务器上配置mariadb,但仍然需要很长时间才能返回查询,而且大部分都没有返回。

Mariadb版本:10.1.31-1服务器有50GB Ram和2200 Ghz * 10核心Centos7作为OP

目标数据库目前有非常庞大的innodb表,没有很好的索引。没有任何其他表类型只是innodb。

目前我正在进行一些嵌套的选择查询,并将结果保存到另一个空插入或替换为空克隆数据库。

举个例子:

REPLACE INTO db1.table1
SELECT * FROM db0.table1 WHERE ART_ID IN (
    SELECT ART_ID FROM db0.table2 WHERE BRA_ID IN (
        SELECT BRA_ID FROM db0.table3 WHERE BRAND IN (
            SELECT BRAND FROM db0.table4 WHERE ID IN (... bunch of comma seperated ids)
        )
    )
);

唯一的连接来自本地和/或只有一个远程连接。服务器的唯一任务是将大量数据过滤到另一个数据库,没有Web服务器等。

我把/etc/my.cnf文件放在下面。我对这个文件做了很多测试,所以你可能会看到一些无用的补充。

问题是:cnf文件中是否有任何未命中配置;还有其他配置提示等在合理的时间内运行那些查询。

它工作得更好,但在我更改配置或/和更新服务器后,一切都变慢了。 (是的,我在更新db版本后也更新了表格)

# The MySQL server
[mysqld]
performance_schema=0
bind-address = 0.0.0.0
max_connections = 32
socket      = /var/lib/mysql/mysql.sock
skip-external-locking
max_allowed_packet = 1024M

connect_timeout=300
wait_timeout=1200
interactive_timeout=300

key_buffer_size = 2G
bulk_insert_buffer_size=256M
sort_buffer_size = 32M
#read_buffer_size = 8M
#read_rnd_buffer_size = 32M
myisam_sort_buffer_size = 32M
join_buffer_size=32M
#max_heap_table_size= 8G
tmp_table_size=8G
concurrent_insert=2
#external-locking=FALSE
#open_files_limit=50000

default-storage-engine=innodb
innodb_file_per_table=1

#lower_case_table_names=1

# Try number of CPU's*2 for thread_concurrency
innodb_write_io_threads=10
innodb_read_io_threads=20
#innodb_buffer_pool_instances=8
#thread_stack = 1M
#thread_cache_size = -1

innodb_buffer_pool_size = 16G

#query_cache_limit = 1073741824
#query_cache_size = 1073741824
#query_cache_type = 1

query_cache_size=0
query_cache_type=0

#innodb_additional_mem_pool_size = 20M
# Set .._log_file_size to 25 % of buffer pool size

innodb_fast_shutdown=0

#innodb_log_file_size = 1G
#innodb_log_buffer_size = 8M
#innodb_flush_log_at_trx_commit = 1
#innodb_lock_wait_timeout = 0
innodb_lock_wait_timeout = 1073741823
innodb_thread_concurrency=0
innodb_commit_concurrency=0
innodb_flush_method=O_DSYNC
innodb_log_compressed_pages = 0
#innodb_flush_neighbors = 0
#innodb_adaptive_hash_index_partitions = 8


log-bin=mysql-bin
server-id   = 1

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash

[isamchk]
key_buffer = 384M
sort_buffer = 384M
read_buffer = 256M
write_buffer = 256M

[myisamchk]
key_buffer = 384M
sort_buffer = 384M
read_buffer = 256M
write_buffer = 256M

[mysqlhotcopy]
interactive-timeout

我使用了percona向导并合并了这些建议。目前my.cnf在下面。

我昨天晚上(2018-03-05 22:41:30 UTC)运行php应用程序,但是mysql仍然无法返回任何结果。

应用程序只添加限制10000和偏移量(我不想从头开始,我正在跟踪最后一个偏移并从那一点开始。)

目前我打算删除并重新安装mariadb :((这将是情绪反应)

# Generated by Percona Configuration Wizard (http://tools.percona.com/) version REL5-20120208

[mysql]

# CLIENT #
port                           = 9999
socket                         = /var/lib/mysql/mysql.sock

[mysqld]

# GENERAL #
port                           = 9999
user                           = mysql
default-storage-engine         = InnoDB
socket                         = /var/lib/mysql/mysql.sock
pid-file                       = /var/lib/mysql/mysql.pid

# MyISAM # - there is no myisam table
key-buffer-size                = 32M
myisam-recover-options         = FORCE,BACKUP

# SAFETY #
max-allowed-packet             = 16M
max-connect-errors             = 1000000
skip-name-resolve

# DATA STORAGE #
datadir                        = /var/lib/mysql/

# BINARY LOGGING #
log-bin                        = /var/lib/mysql/mysql-bin
expire-logs-days               = 14
sync-binlog                    = 1

# CACHES AND LIMITS #
tmp-table-size                 = 32M
max-heap-table-size            = 32M
query-cache-type               = 0
query-cache-size               = 0
max-connections                = 30
#thread-cache-size              = 16
open-files-limit               = 65535
table-definition-cache         = 1024
table-open-cache               = 2048

# INNODB #
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 2
innodb-log-file-size           = 5G
innodb-flush-log-at-trx-commit = 1
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 42G
innodb-buffer-pool-instances   = 42


thread_cache_size=100
innodb_lru_scan_depth=100
innodb_purge_threads=4
innodb_read_io_threads=64
innodb_write_io_threads=64
innodb_thread_concurrency=0
max_seeks_for_key=32
max_write_lock_count=16
thread_concurrency=35

innodb_fast_shutdown=0
innodb_file_per_table=1
default-storage-engine=innodb
concurrent_insert=2
join_buffer_size=32M
tmp_table_size=8G
read_buffer_size = 8M

# LOGGING #
log-error                      = /var/lib/mysql/mysql-error.log
log-queries-not-using-indexes  = 0
slow-query-log                 = 1
slow-query-log-file            = /var/lib/mysql/mysql-slow.log
mysql optimization mariadb centos7 configure
6个回答
1
投票

问题中的my.cnf数据与SHOW GLOBAL VARIABLES不匹配;值。

请使用此链接 https://mariadb.com/kb/en/library/configuring-mariadb-with-mycnf/ 帮助获得准确匹配的值以获得帮助。

那么,为my.cnf [mysqld]部分考虑的建议包括:

innodb_buffer_pool_size=8G  # from > 40G (95% of RAM will not work well)
innodb_lru_scan_depth=100  # from 1024  see refman every second digging too deep
log_warnings=2  # from 1 to include connection errors more detail
max_connect_errors=10  # from 1,000,000 no need to waste a million cycles
thread_cache_size=100  # from 16  CAP per V8 MySQ to be prepared for volume
have_symlink=NO  # to protect you server, unless you NEED it
innodb_purge_threads=4  # from 1  to accommodate when needed
innodb_read_io_threads=64  # from 4 see dba.stackexhange.com Q 5666 9/12/11 Rolando
innodb_write_io_threads=64  # from 4  per Rolando to use multi-core
innodb_thrad_concurrency=0  # another part of multi-core enabling
max_seeks_for_key=32  # from huge number, not found in 32, will not be found
max_write_lock_count=16  # give RD opportunity after nn locks
thread_concurrency=35  # to limit concurrent processing load

@Erce,请在正确的活动my.cnf中应用。撤回我的重做你的mysqld部分的提议。


1
投票

我使用了percona向导并合并了这些建议。目前my.cnf在下面。

我昨天晚上(2018-03-05 22:41:30 UTC)运行php应用程序,但是mysql仍然无法返回任何结果。

应用程序只添加限制10000和偏移量(我不想从头开始,我正在跟踪最后一个偏移并从那一点开始。)

[mysql]

# CLIENT #
port                           = 9999
socket                         = /var/lib/mysql/mysql.sock

[mysqld]

# GENERAL #
port                           = 9999
user                           = mysql
default-storage-engine         = InnoDB
socket                         = /var/lib/mysql/mysql.sock
pid-file                       = /var/lib/mysql/mysql.pid

# MyISAM # - there is no myisam table
key-buffer-size                = 32M
myisam-recover-options         = FORCE,BACKUP

# SAFETY #
max-allowed-packet             = 16M
max-connect-errors             = 1000000
skip-name-resolve

# DATA STORAGE #
datadir                        = /var/lib/mysql/

# BINARY LOGGING #
log-bin                        = /var/lib/mysql/mysql-bin
expire-logs-days               = 14
sync-binlog                    = 1

# CACHES AND LIMITS #
tmp-table-size                 = 32M
max-heap-table-size            = 32M
query-cache-type               = 0
query-cache-size               = 0
max-connections                = 30
#thread-cache-size              = 16
open-files-limit               = 65535
table-definition-cache         = 1024
table-open-cache               = 2048

# INNODB #
innodb-flush-method            = O_DIRECT
innodb-log-files-in-group      = 2
innodb-log-file-size           = 5G
innodb-flush-log-at-trx-commit = 1
innodb-file-per-table          = 1
innodb-buffer-pool-size        = 42G
innodb-buffer-pool-instances   = 42


thread_cache_size=100
innodb_lru_scan_depth=100
innodb_purge_threads=4
innodb_read_io_threads=64
innodb_write_io_threads=64
innodb_thread_concurrency=0
max_seeks_for_key=32
max_write_lock_count=16
thread_concurrency=35

innodb_fast_shutdown=0
innodb_file_per_table=1
default-storage-engine=innodb
concurrent_insert=2
join_buffer_size=32M
tmp_table_size=8G
read_buffer_size = 8M

# LOGGING #
log-error                      = /var/lib/mysql/mysql-error.log
log-queries-not-using-indexes  = 0
slow-query-log                 = 1
slow-query-log-file            = /var/lib/mysql/mysql-slow.log

1
投票

@二册

需要删除这三条线(就在LOGGING区域之前)

join_buffer_size=32M
tmp_table_size=8G
read_buffer_size = 8M

LOGGING

tmp_table_size之前与max_heap_table_size准确匹配。这条线后来负责并让你失衡,这是不好的。

join_buffer_size和read_buffer_size正在扼杀你的RAM足迹。请使用mysqlcalculator.com了解原因。


1
投票

性能问题主要在于查询的制定,而不一定在调优或索引中。

查询表达方式

一般情况下,将IN ( SELECT ... )变成JOIN

解决最后一步:

SELECT  bra_id
    FROM  t3
    JOIN  t4  ON  t3.brand = t4.brand
    WHERE  t4.id IN (...commalist...)

带索引:

t4: INDEX(id, brand)
t3: INDEX(brand, bra_id)

这从t4开始,寻找各种ID,然后将它们映射到品牌。然后它通过品牌达到t3以获得bra_id。

我会让你练习接下来的两个步骤来完成t2到t1。

调整建议

不要盲目增加my.cnf中的值,它会让你陷入困境。

innodb_buffer_pool_size = 35G  -- the most important

42G可能没问题 - 如果你没有在同一台服务器上运行太多其他应用程序。 42实例可能有效。有人说16个实例应该是最大值。

其余的可调参数可能会被单独留下。

max_heap_table_size= 8G
tmp_table_size=8G

那些是危险的高。有了它们,每个连接可以分配8GB(或多于一次)。但是你只有50GB的RAM。最好将它们设置为不超过RAM的1%(500M或更低; 32M应该没问题)。

#lower_case_table_names=1

留下评论。任何试图覆盖操作系统所需内容的尝试都可能让你陷入深深的困境。

port                           = 9999

默认3306有什么问题?

其他

“应用程序在6小时内抓获10000件物品。对于下一个8小时的物品块” - 请为正在阅读的4个表提供SHOW CREATE TABLE,以及正在写入的表。并告诉我们桌子有多大。我怀疑你正在对目标表中的索引更新进行颠覆。有一个简单的解决方案。

检查mysql是否在交换。


1
投票

我想我需要更改选择查询样式,我会尝试提供的查询备选方案,因为它不起作用,查询仍然要慢(我假设)

但这些是当前的服务器统计数据(49GB RAM,10核心)和mysqls虚拟内存大约47~GB,这很好,没有任何其他应用程序正在运行。我觉得还好吗?

tuning-primer.sh
https://pastebin.com/bcjS1PWf

mysqltuner.pl
https://pastebin.com/mXUTLPQ6

my.cnf
https://pastebin.com/9jMLzhZS

1
投票

使用3/15/18发布的数据为my.cnf-ini [mysqld]部分提供的建议

thread_cahce_size=40  # from 20, 8 required for overhead, room to wiggle
innodb_io_capacity=400  # from 200   new iostat -x will confirm use
# read_buffer_size=8388608  # lead with # for default of 128K - extreme at 8M
read_rnd_buffer_size=128K  # from 256K will affect handler_read_rnd_next 
sync_binlog=32  # from 1 sec frequency, unless you fear recovery required
# join_buffer_size=4M  # lead with # for default of 128K
key_buffer_size=1M  # from 32M less than 1M used - primarily Innodb tables
innodb_adapative_max_sleep_delay=15  # from 150000 (15 secs - n0 other users)
innodb_buffer_pool_instances=8  # from 42 to minimize mgmt. overhead
innodb_buffer_pool_size=40G  # from 44G allow OS a little breathing room
innodb_change_buffer_max_size=3  # from 25% - no need to set aside 10G when not changing anything significant
innodb_doublewrite=OFF  # from ON you are not a PROD effort - crash recovery NA for run of this instance
innodb_print_all_deadlocks=ON  # from OFF you always need in error log
innodb_read_ahead_threshold=8  # from 56, why wait to read NXT extent?
innodb_stats_sample_pages=32  # from 8 for more accurate index cardinality 
log_warnings=2  # from 1 to record addl connection error details
max_join_size=1000000000  # from more huge number to 1B rows max for join
sql_select_limit=1000000000  # from more huge number to 1B rows selected
query_alloc_block_size=32K  # from 16K - minimize RAM alloc AvgQrySz 20K
query_cache_type=0  # for OFF, not used
query_cache_size=0  # from 8M  not needed for one time selections
query_cache_limit=1K  # from 256K, just to keep the framework, in case QC needed
query_cache_min_res_unit=512  # from 2K for optimal QC storage when QC used
query_prealloc_size=32K  # from 24K to minimize RAM alloc for parsing 
transaction_alloc_block_size=32K  # from 8K to minimize RAM alloc
transaction_prealloc_size=32K  # from 4K to minimize RAM alloc
updatable_views_with_limit=NO  # from YES to reduce handler_external_lock count

这个可能必须回到YES - 它是DYNAMIC变量

请在离开会话之前找到您的ONE com_stmt_prepare代码并确保它已关闭,以释放每个refman PREPARE或mysql_stmt_prepare for API的资源。

运行之后,在运行有问题的查询之前,请考虑为每个表使用ALTER TABLE tbl_name ENGINE = INNODB以利用其他页面以获得更好的基数,然后尝试长时间运行的查询。

© www.soinside.com 2019 - 2024. All rights reserved.