I spent the last days studying alternatives to update my database , I have studied databases as MemSQL , VoltDB , and many other databases. I have a specific problem , in which case I have real-time data updates , and need to show this data quickly to my user. However I can not migrate to NoSQL solutions for the needs of Joins , ACID , Group By , among others.
I'm currently using the following structure:
1 Server 64 GB Ram 1600 Mhz / Xeon E5 3.7 Ghz / 160 GB SSD
MySQL InnoDB engine to save the data and not lose them and MySQL Memory Engine to perform the Selects in real time updated via Trigger.
This structure is good , but do not increase much my performace and my amount of records is increasing too .
From that, I started to test other database, looking for a solution that could scale and found MySQL Cluster . I have tested MySQL Cluster the last days and the performace it is far below the MySQL Memory Engine, comparative 4-5x slower for some queries .
Have my infrastructure for MySQL Cluster are 4 machines with the same configuration above , one NDB Manager , MySQL SQL Node 1 , Node 2 Date ( 1 Node Group with replication) . In this case I have a super hardware, because as I said , I have a major concern with real time.
A case I'm testing is as follows , I have a table with 5 million records , with one column I need to perform a " ( count (distinct (column ) ) " are using Index BTREE . My query is basically the following
MySQL Memory Engine :
select sql_no_cache COUNT(DISTINCT(id)) from my_data;
/* Affected rows: 0 Registros encontrados: 1 Avisos: 0 Duração de 1 query: 0,109 sec. */
MySQL Cluster :
select sql_no_cache COUNT(DISTINCT(id)) from my_data;
/* Affected rows: 0 Registros encontrados: 1 Avisos: 0 Duração de 1 query: 0,485 sec. */
For MySQL Memory Engine, i have a my.cnf boosted , some values are bigger than I need , but it is working as well , see below:
[mysqld]
socket = /var/run/mysqld/mysqld.sock
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
# * Fine Tuning
key_buffer = 16G
max_allowed_packet = 4G
table_open_cache = 16384
sort_buffer_size = 8G
read_buffer_size = 8G
read_rnd_buffer_size = 16G
myisam_sort_buffer_size = 16G
thread_cache_size = 256
thread_concurrency = 128
thread_stack = 8192K
myisam-recover = BACKUP
max_connections = 5000
# * Query Cache Configuration
query_cache_limit = 2G
query_cache_size = 8G
tmp_table_size = 16G
max_heap_table_size = 32G
# * Logging and Replication
general_log_file = /var/log/mysql/mysql.log
general_log = 1
log_error = /var/log/mysql/error.log
log_slow_queries = /var/log/mysql/mysql-slow.log
long_query_time = 1
log-queries-not-using-indexes
log_bin = /var/log/mysql/mysql-bin.log
expire_logs_days = 10
max_binlog_size = 100M
# INNODB
innodb_buffer_pool_size = 48G
innodb_additional_mem_pool_size = 32G
innodb_file_per_table = 1
innodb_file_format = barracuda
[mysqldump]
quick
quote-names
max_allowed_packet = 8G
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 16G
[myisamchk]
key_buffer_size = 24G
sort_buffer_size = 24G
read_buffer = 16G
write_buffer = 16G
As for MySQL Cluster , the Config.ini file is as follows:
[ndbd default]
# Options affecting ndbd processes on all data nodes:
NoOfReplicas=2 # Number of replicas
DataMemory=32G # How much memory to allocate for data storage
IndexMemory=16G # How much memory to allocate for index storage
# For DataMemory and IndexMemory, we have used the
# default values. Since the "world" database takes up
# only about 500KB, this should be more than enough for
# this example Cluster setup.
MaxNoOfTables=4096
MaxNoOfTriggers=3500
MaxNoOfAttributes=10000
MaxNoOfOrderedIndexes=1000
MaxNoOfUniqueHashIndexes=1000
MaxNoOfConcurrentIndexOperations=32K
MaxNoOfConcurrentOperations=128K
SharedGlobalMemory=1G
DiskPageBufferMemory=1G
[ndb_mgmd]
NodeId=20
# Management process options:
hostname=192.168.0.1 # Hostname or IP address of MGM node
datadir=/var/lib/mysql-cluster # Directory for MGM node log files
[ndbd]
#Data Node 1
NodeId=1
NodeGroup=0
hostname=192.168.0.2 # Hostname or IP address
datadir=/usr/local/mysql/data # Directory for this data nodes data files
[ndbd]
#Data Node 2
NodeId=2
NodeGroup=0
hostname=192.168.0.3 # Hostname or IP address
datadir=/usr/local/mysql/data # Directory for this data nodes data files
[mysqld]
# SQL Node 1
NodeID=11
hostname=192.168.0.4 # Hostname or IP address
So what's wrong for MySQL Cluster not have the same performace MySQL Memory Engine?
Related
I can't find the source of the issue on our Master/Slave replication .
Today i was updating the Master and suddenly got the following error from the slave
Error 'The table 'caching_api' is full' on query.
Query: '
ALTER TABLE `caching_api`
ADD UNIQUE INDEX `id` (`id`) USING BTREE ,
ADD INDEX `search` (`component`, `method`) USING BTREE
It's not a disk issue , the Slave is an exact replicate of the Master
And my.cnf config :
[mysqld]
#
# * Basic Settings
#
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /data/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
key_buffer = 16M
max_allowed_packet = 128M
thread_stack = 192K
thread_cache_size = 64
table_open_cache = 3000
join_buffer_size = 128k
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover = BACKUP
max_connections = 4000
wait_timeout = 150
interactive_timeout = 30
innodb_buffer_pool_size = 25G
innodb_log_file_size = 1G
innodb_buffer_pool_instances = 10
tmp_table_size = 256M
max_heap_table_size = 256M
innodb_flush_log_at_trx_commit = 2
query_cache_limit = 64M
query_cache_size = 256M
relay_log_space_limit = 10G
server-id = 2
relay-log = /var/log/mysql/mysqld-relay-bin
expire_logs_days = 1
max_binlog_size = 100M
slave-skip-errors = 1062,1054
[mysqldump]
quick
quote-names
[mysql]
#no-auto-rehash # faster start of mysql but no tab completition
[isamchk]
key_buffer = 16M
Update to questions from comments :
When i try to run the query directly on the SLAVE :
caching_api table status
Slave Disk Info
ibdata1 about 36GB
ulimit -a
The manual doesn't rule out the possibility of a full disk.
If a table-full error occurs, it may be that the disk is full or that
the table has reached its maximum size. The effective maximum table
size for MySQL databases is usually determined by operating system
constraints on file sizes, not by MySQL internal limits.
But since have checked that already before posting this question. So the only other possiblility is that maximum table size has been reached.
I'm running this server for data mining purposes. It runs several compute intensive data mining applications parallely and does simultaneous access to the MySQL server.
Here are the configuarations.
Server config: 8 core Intel Xeon, 16gb RAM, 500 GB SAS drive
MySQL my.cnf
[client]
#password = [your_password]
port = 3306
socket = /var/lib/mysql/mysql.sock
[mysqld]
# generic configuration options
port = 3306
socket = /var/lib/mysql/mysql.sock
datadir = /database/mysql
log_bin = OFF
expire-logs-days = 3
pid-file = /database/mysql/localhost.localdomain.pid
back_log = 50
max_connections = 3000
max_connect_errors = 100
table_open_cache = 2048
max_allowed_packet = 16M
binlog_cache_size = 1M
max_heap_table_size = 64M
read_buffer_size = 128M
read_rnd_buffer_size = 32M
sort_buffer_size = 32M
join_buffer_size = 8M
thread_cache_size = 8
thread_concurrency = 4
query_cache_size = 64M
query_cache_limit = 2M
ft_min_word_len = 4
default-storage-engine = innodb
thread_stack = 192K
transaction_isolation = REPEATABLE-READ
tmp_table_size = 64M
log-bin = mysql-bin
binlog_format = mixed
server-id = 1
key_buffer_size = 32M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
innodb_additional_mem_pool_size = 32M
innodb_buffer_pool_size = 4G
innodb_data_file_path = ibdata1:10M:autoextend
#innodb_data_home_dir = <directory>
innodb_write_io_threads = 8
innodb_read_io_threads = 8
#innodb_force_recovery = 6
innodb_thread_concurrency = 0
innodb_flush_log_at_trx_commit= 2
#innodb_fast_shutdown
innodb_log_buffer_size = 8M
innodb_log_file_size = 1G
innodb_log_files_in_group = 3
#innodb_log_group_home_dir
innodb_max_dirty_pages_pct = 90
#innodb_flush_method = O_DSYNC
innodb_lock_wait_timeout = 120
[mysqldump
quick
max_allowed_packet = 16M
[mysql]
auto-rehash
[myisamchk]
key_buffer_size = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
open-files-limit = 8192
There are only 2 users who access this server which includes me. On peak hour I get this
mysql > show processlist
...
120 rows in set
Which shows that around 120 connections are established to the mysql server during peak computation hours. MySQL consumes around 9.5gb of memory and uses 98-99% CPU which I can still live with. But during this time a front end site build with php/javascript takes around 1 - 2 min to load which is because mysql responds very slowly during these hours. While normally it takes somewhere around 890ms to 4 seconds.
I want to know how to further optimize the mysql server configuration. Currently as can be seen from the posted my.cnf , buffer pool is at 4GB and max number of connections are set at 3000 . All the tables are Innodb with proper indexes, but in my case transaction safety is not a issue the main and the only issue is performance. The data mining applications uses MySQL C API Connector and each has around 24 parallel threads running which equals to 24 simultaneous connections to MySQL
How can I further optimize the mysql server configuration so that I may get a reasonable response time of around 10 - 15 seconds for front end access . Please let me know if there is any way to optimize this further.
You really should dedicate another server just for data mining and set up replication between your MySQL servers. Data mining application should use transactions to union multiple small queries into blocks. This way your site will not wait for other queries to be executed and synchronization would be made in background without visible lag.
Another options is to cache as much as possible and hope that user will not request data that is not in cache when heavy hours are.
But I prefer to do both of this things so you'll have 100% reliable service.
I am on linux box running only mysql with 8 cores and 16GB ram. All connections come from web server on another machine in the same network running php with codeigniter.
I cannot get more than 150 connections on mysql.
My my.cnf is:
[mysqld]
user=mysql
port = 3306
socket = /tmp/mysql.sock
datadir = /usr/local/mysql/var/
skip-external-locking
max_connections=500
max_user_connections=500
open-files-limit = 500
key_buffer_size = 2048M
max_allowed_packet = 32M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
myisam_sort_buffer_size = 128M
thread_cache_size = 250
table_definition_cache = 1024
query_cache_size = 32M
query_cache_limit = 32M
table_cache=1024
max_heap_table_size=1024M
key_buffer=2048M
wait_timeout=60
thread_concurrency = 16
long_query_time = 1
tmp_table_size=256M
show status returns that max_connections and max_user_connections to be 500.
Since mysql is saying that connection limit is 500, I thought there are other setting in PHP, apache or codeigniter that is limiting the requests to mysql, but I cannot find any. I've searched google for few days trying to find answers without any luck.
Are there limits set on any of the above mentioned software? I will post configs if necessary.
Thank you.
Check the Max number of Apache worker processes (ServerLimit and MaxClients) in httpd.conf. Assuming a fixed number of connections per worker, you might be maxing out your number of workers, so nothing is requesting new MySQL connections.
Sorry, just found this on Google, but your config is foobar
max_connections=500
open-files-limit = 500
table_open_cache = 512
table_definition_cache = 1024
open-files-limit: 500 #; not good!
table_open_cache: 512... * 2+ open-files per table = 1024 open-files used minimum
max_connections: 500 each open connection starts a new file handle to buffer.
Your mysql will open some 130 tables just to start (core tables) which leaves you with a mere 240 file handles to share between data queries and connections. For each connection with a table query, 3+ file handles are consumed (connection, data table, index file(s)). That maxes your open-files long before you get 150 connections. open-files-limit needs to start >2048 for that kind of DB usage.
more help:
show global status like '%open%';
show global status like '%onnect%';
see for yourself how many files/connections are actually in use. some operating systems (Windows XP) hard limit files/network connections. try googling "mysql 'YOUR-OS' 150 connections" and see if that is the limiting factor.
I have a Xeon 2.0Ghz server (12 cores) with 16GB memory, running Apache and mySQL for a website with around 50,000 records in InnoDB (Percona). My queries used to return in about 0.17 to 0.25 seconds, then I ran the Percona tools mySQL optimizer, uploaded the new my.cnf file and suddenly the same queries are taking 1.20 to 1.30 seconds, so about 5x longer.
What did I do wrong? Here are my old and new my.cnf files"
NEW:
[mysqld]
default_storage_engine = InnoDB
key_buffer_size = 32M
myisam_recover = FORCE,BACKUP
max_allowed_packet = 16M
max_connect_errors = 1000000
log_bin = /var/lib/mysql/mysql-bin
expire_logs_days = 14
sync_binlog = 1
tmp_table_size = 32M
max_heap_table_size = 32M
query_cache_type = 0
query_cache_size = 0
max_connections = 200
thread_cache_size = 50
open_files_limit = 65535
table_definition_cache = 1024
table_open_cache = 2048
innodb_flush_method = O_DIRECT
innodb_log_files_in_group = 2
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
innodb_buffer_pool_size = 12G
log_error = /var/lib/mysql/mysql-error.log
log_queries_not_using_indexes = 1
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
OLD:
[mysqld]
innodb_buffer_pool_size = 12000M
innodb_log_file_size = 256M
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16M
innodb_additional_mem_pool_size = 20M
innodb_thread_concurrency = 20
read_rnd_buffer_size=50M
query_cache_size=128M
query_cache_type=1
tmp_table_size=512M
wait_timeout=90
query_cache_limit=64M
key_buffer_size=128M
max_heap_table_size=512M
max_allowed_packet=32M
log_slow_queries
log-queries-not-using-indexes
long_query_time = 1
Are you swapping at all after running for a while?
You might try turning down your innodb_buffer_pool_size since you say the server is also running Apache. At the moment it looks like MySQL has the potential to use up all the server's memory for itself and leave nothing for the OS and Apache.
Try setting innodb_buffer_pool_size to 8G and then set innodb_log_file_size to 2G.
You can probably up your innodb_thread_concurrency as well, but since it isn't a dedicated MySQL server it may be fine at the default of 8. It depends on what CPU you have but the docs say:
The correct value for this variable is dependent on environment and
workload. You will need to try a range of different values to
determine what value works for your applications. A recommended value
is 2 times the number of CPUs plus the number of disks.
So play around with that and see what works best.
Also, is your database larger than the amount of RAM you have or could your entire DB fit in memory?
Just keep in mind that since you are running Apache on the same server, Apache is going to want to create a bunch of its own threads and consume as much memory as required for all the server processes and if you're running something like PHP that's going to take up memory as well.
You're going to have to find a good balance where both Apache and MySQL can both perform at maximum capacity on the same system but where neither one uses so much memory that the other has to swap.
Additional ways you can troubleshoot or profile performance would be to check your slow query log and run explains on the slow queries. In addition, you can install the Percona toolkit and run pt-query-digest to analyze your performance. Read the docs here.
Currently I have 3 servers running, 2 remote, Main server running MySQL 5.5.24 and backup running MySQL 5.1.63 and 1 local running MySQL 5.5.20 for development. The main server is used for reporting purposes; currently have 144 tables (MyISAM and InnoDB), and about 80gb of data, the larger tables have about 13 million rows each one.
On the remote servers I have very limited access through webmin, because of this I can’t make the changes directly, I need to ask to IT department for them.
I’m having some serious performance issues on the Main server since a MySQL crash we had last month. The server was running a development release which had some disk writing bugs, after the recovery we installed the MySQL 5.5.23 version and that’s when the performance issues began. We recently installed MySQL 5.5.24 (lastest stable version) but we still have the performance issues
Here are the servers configurations, all are dedicated servers:
Main:
Operating system: Gentoo Linux
Kernel and CPU: Linux 2.6.31-gentoo-r6 on x86_64
Processor information: Intel(R) Xeon(TM) CPU 2.66GHz, 8 cores
Real memory (ram): 23.55 GB total
Virtual memory: 3.74 GB total
Local disk space: 463.38 GB total (about 30% free)
Backup:
Operating system: Gentoo Linux
Kernel and CPU: Linux 2.6.31-gentoo-r6 on x86_64
Processor information: Intel(R) Core(TM)2 Duo CPU E6405 # 2.13GHz, 2 cores
Real memory (ram): 15.68 GB total
Virtual memory: 16.01 GB total
Local disk space: 4.73 TB total (about 80% free)
Development:
Operating system: Ubuntu Linux 9.04
Kernel and CPU: Linux 2.6.32-33-server on x86_64
Processor information: Intel(R) Core(TM)2 Duo CPU E6550 # 2.33GHz, 2 cores
Real memory (ram): 1.95 GB total
Virtual memory: 5.65 GB total
Local disk space: 141.15 GB total (about 5% free)
All the servers have the same my.cnf configuration, except for the innodb_buffer_pool_size
my.cnf
[mysqld]
back_log = 50
max_connections = 100
max_connect_errors = 10
table_open_cache = 2048
max_allowed_packet = 16M
binlog_cache_size = 1M
max_heap_table_size = 64M
read_buffer_size = 2M
read_rnd_buffer_size = 16M
sort_buffer_size = 8M
join_buffer_size = 8M
thread_cache_size = 8
thread_concurrency = 8
query_cache_size = 64M
query_cache_limit = 2M
ft_min_word_len = 4
default-storage-engine = MYISAM
thread_stack = 262K
stored_program_cache= 1024
transaction_isolation = REPEATABLE-READ
tmp_table_size = 64M
binlog_format=mixed
slow_query_log
long_query_time = 2
key_buffer_size = 512M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover
innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 8G
innodb_data_file_path = ibdata1:10M:autoextend
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_thread_concurrency = 16
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 8M
innodb_log_file_size = 256M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 240
server-id = 1
event_scheduler = 1
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
open-files-limit = 8192
I’ve tried several large Stored Procedures with lots of columns and data and the backup server is about 10x faster than the main server, and running them on development server its about 5x faster than main.
Since the main server and the backup server are on the same remote location and through a VPN I know there are no connection speed issues.
I can’t post the Stored Procedures code, but I know the issue is on the final SELECT since the creation of all temporary tables are pretty fast, and I can see in the MySQL monitor (using SHOW FULL PROCESSLIST) that the SELECT is taking 95% of the time. Most of the Stored Procedures works with tons of data, with multiples joins.
Any Ideas why the main server could be having so bad performance even it’s the most powerful?
We've been looking for reported performance bugs of the latest versions, but what we found didn't help at all http://bugs.mysql.com/bug.php?id=44585
I'll really appreciate any help
Would this question better be asked on server fault? It's my first question
Sorry about my english.
Are the same tables involved in all of the problematic SELECT statements in the Stored Procedures you tried? Perhaps the index statistics need to be rebuilt on some of them - check out the OPTIMIZE TABLE command.
Finally we moved the DB to another server, new version of MySQL