MySQL Sicherheit und Performance

GoMoPa

New Member
Hallo,
wir haben einen dedizierten Server mit 6GB Ram und 2xXEON 2.3 GHZ.

Wir haben zur Zeit massive Probleme, dass der Datenbankserver abstürzt bzw. überlastet ist, sehr viele Firmen versuchen unseren Content zu replizieren bzw. versuchen Massenanfragen an unseren Server.

Ich habe aus Sicherheit-/Performancegründen bereits den Proxy/Opensource Firewall GreenSQL davor geschaltet, leider stürzt dieser Dienst auch in regelmässigen Abständen mit der Fehlermeldung:

Warning: mysql_connect() [function.mysql-connect]: Lost connection to
MySQL server at 'reading initial communication packet', system error:
111 in ...functions.lib.php
on line 252
SQL Error:Lost connection to MySQL server at 'reading initial
communication packet', system error: 111

Hat jemand Erfahrungen mit MySQL-Sicherheit und Performancenoptimierung, erkennt jemand Redudanzen in nachfolgender My.cnf? Für Tipps und Hilfe wäre ich dankbar.

Code:
[mysqld]
set-variable=local-infile=0
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibility with mysql 3.x
# clients (those using the mysqlclient10 compatibility package).
old_passwords=1


#max_connections=1000
#query_cache_size=128M
#thread_cache_size=8

#max_connections=1000

ft_min_word_len=3

#key_buffer_size = 64M
#thread_cache_size = 40
#query_cache_size = 16M
#query_cache_limit = 16M
#thread_concurrency = 3
#tmp_table_size = 8M
#sort_buffer_size = 1M
#read_buffer_size = 1M
#read_rnd_buffer_size = 1M
#myisam_sort_buffer_size = 128M
#thread_cache_size = 32

join_buffer_size=1M
sort_buffer_size=1M
read_buffer_size=1M
read_rnd_buffer_size=1M
table_cache=256M
#max_allowed_packet=4M
key_buffer=256M
key_buffer_size=256M
thread_cache=256M
thread_concurrency=2
thread_cache_size=40
thread_stack=128K
concurrent_insert=2
query_cache_limit=256M
query_cache_size=4M
query_cache_type=1
skip-bdb
#skip-innodb
interactive_timeout=120
max_connections = 500
max_user_connections = 500

wait_timeout= 30
connect_timeout= 30
long_query_time = 2
# Log Querys
log-slow-queries=/var/log/mysql/mysql-slow.log

#key_buffer = 16M
#net_buffer_length = 8K

#sort_buffer_size = 128K
#myisam_sort_buffer_size = 256K
#join_buffer_size = 2M

#query_cache_size = 4M
#thread_cache = 32
#table_cache = 1024
#max_allowed_packet = 256K

#max_connections = 60
#low_priority_updates = 1
#long_query_time = 2
#[mysqld]
#query_cache_limit       = 1M
#query_cache_size        = 32M
#query_cache_type        = 1
#thread_concurrency     = 4
#thread_cache           = 64

[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
 
Gegen übermäßige Zugriffsversuche hilft mod_evasive (sofern Ihr den Apache-Webserver einsetzt).
Ansonsten wäre interessant, ob der mysqld richtig läuft. Dazu müsstest Du mal in das Logfile des mysqld schauen, ob da irgendwelche Fehlermeldungen auftauchen und die Ausgabe von 'top' hier posten (bitte in [noparse]
Code:
...
[/noparse]-Tags).
Eine erste Anlaufstelle dürften sicherlich die Ausgaben des tuning-primer.sh-Scriptes sein, das Du in diesem [Thread=14308]Thread[/Thread] findest -- die Ausgaben am Besten auch mal posten. Den Thread solltest Du Dir auf jeden Fall mal durchlesen, denn dort ist eigentlich alles Relevante zu finden, was Du zur richtigen Konfiguration von mysqld+Apache wissen musst.
 
TuningPrimer Ergebnis:

Code:
[root@ded1461 bin]# tuning-primer.sh
mysqld is alive

        -- MYSQL PERFORMANCE TUNING PRIMER --
             - By: Matthew Montgomery -

MySQL Version 5.0.45-log x86_64

Uptime = 0 days 16 hrs 10 min 48 sec
Avg. qps = 37
Total Questions = 2161627
Threads Connected = 2

Warning: Server has not been running for at least 48hrs.
It may not be safe to use these recommendations

To find out more information on how each of these
runtime variables effects performance visit:
[url=http://dev.mysql.com/doc/refman/5.0/en/server-system-variables.html]MySQL :: MySQL 5.0 Reference Manual :: 5.1.3 Server System Variables[/url]
Visit [url=http://www.mysql.com/products/enterprise/advisors.html]MySQL :: MySQL Enterprise Advisors[/url]
for info about MySQL's Enterprise Monitoring and Advisory Service

SLOW QUERIES
The slow query log is enabled.
Current long_query_time = 2 sec.
You have 2705 out of 2161656 that take longer than 2 sec. to complete
Your long_query_time seems to be fine

BINARY UPDATE LOG
The binary update log is NOT enabled.
You will not be able to do point in time recovery
See [url=http://dev.mysql.com/doc/refman/5.0/en/point-in-time-recovery.html]MySQL :: MySQL 5.0 Reference Manual :: 6.3 Point-in-Time Recovery[/url]

WORKER THREADS
Current thread_cache_size = 40
Current threads_cached = 36
Current threads_per_sec = 0
Historic threads_per_sec = 0
Your thread_cache_size is fine

MAX CONNECTIONS
Current max_connections = 500
Current threads_connected = 5
Historic max_used_connections = 87
The number of used connections is 17% of the configured maximum.
Your max_connections variable seems to be fine.

MEMORY USAGE
Max Memory Ever Allocated : 627 M
Configured Max Per-thread Buffers : 2.00 G
Configured Max Global Buffers : 270 M
Configured Max Memory Limit : 2.27 G
Physical Memory : 5.81 G
Max memory limit seem to be within acceptable norms

KEY BUFFER
175851 * 1024 / 268435456 * 100
Current MyISAM index space = 598 M
Current key_buffer_size = 256 M
Key cache miss rate is 1 : 512
Key buffer free ratio = 0 %
You could increase key_buffer_size
It is safe to raise this up to 1/4 of total system memory;
assuming this is a dedicated database server.

QUERY CACHE
Query cache is enabled
Current query_cache_size = 4 M
Current query_cache_used = 3 M
Current query_cache_limit = 256 M
Current Query cache Memory fill ratio = 83.54 %
Current query_cache_min_res_unit = 4 K
However, 115955 queries have been removed from the query cache due to lack of memory
Perhaps you should raise query_cache_size
MySQL won't cache query results that are larger than query_cache_limit in size

SORT OPERATIONS
Current sort_buffer_size = 1 M
Current read_rnd_buffer_size = 1020 K
Sort buffer seems to be fine

JOINS
Current join_buffer_size = 1.00 M
You have had 3 queries where a join could not use an index properly
You should enable "log-queries-not-using-indexes"
Then look for non indexed joins in the slow query log.
If you are unable to optimize your queries you may want to increase your
join_buffer_size to accommodate larger joins in one pass.

Note! This script will still suggest raising the join_buffer_size when
ANY joins not using indexes are found.

OPEN FILES LIMIT
Current open_files_limit = 65535 files
The open_files_limit should typically be set to at least 2x-3x
that of table_cache if you have heavy MyISAM usage.
Your open_files_limit value seems to be fine

TABLE CACHE
Current table_cache value = 32512 tables
You have a total of 810 tables
You have 1195 open tables.
The table_cache value seems to be fine

TEMP TABLES
Current max_heap_table_size = 16 M
Current tmp_table_size = 32 M
Of 64409 temp tables, 10% were created on disk
Effective in-memory tmp_table_size is limited to max_heap_table_size.
Created disk tmp tables ratio seems fine

TABLE SCANS
Current read_buffer_size = 1020 K
Current table scan ratio = 3557 : 1
read_buffer_size seems to be fine

TABLE LOCKING
Current Lock Wait ratio = 1 : 36
You may benefit from selective use of InnoDB.
If you have long running SELECT's against MyISAM tables and perform
frequent updates consider setting 'low_priority_updates=1'

Top Auszug:

Code:
top - 10:40:29 up 41 days, 7 min,  1 user,  load average: 2.00, 2.99, 3.01
Tasks: 211 total,   4 running, 207 sleeping,   0 stopped,   0 zombie
Cpu(s): 16.7%us,  5.5%sy,  0.0%ni, 76.4%id,  1.3%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   6093956k total,  5633340k used,   460616k free,   224476k buffers
Swap:  2096472k total,      136k used,  2096336k free,  1994828k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13894 mysql     15   0  689m 276m 4752 S  190  4.6 323:59.81 mysqld
10021 apache    22   0  299m  11m 2700 R  100  0.2   0:04.11 httpd
 9402 apache    15   0  366m  25m 4080 S   35  0.4   0:05.22 httpd
 9463 apache    15   0  365m  25m 4012 R   22  0.4   0:00.78 httpd
10004 apache    15   0  360m  19m 3992 S    8  0.3   0:00.44 httpd
10011 apache    15   0  365m  24m 4000 S    8  0.4   0:00.25 httpd
 4772 greensql  15   0 56712 2972 1656 S    6  0.0   3:16.33 greensql-fw
    1 root      15   0 10348  688  572 S    0  0.0   0:09.20 init
    2 root      RT  -5     0    0    0 S    0  0.0   0:05.10 migration/0
    3 root      34  19     0    0    0 S    0  0.0   0:00.01 ksoftirqd/0

Aus Sicherheits-/Performance Gründen wurde bereits der/die Proxy/Opensource Firewall GreenSQL vorgeschalten.

Apache 2 mit PHP5 ist installiert und es läuft Plesk 9.1.

Code:
PHP 5.2.9 (cli) (built: Mar 11 2009 08:22:06)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
    with Zend Extension Manager v1.2.2, Copyright (c) 2003-2007, by Zend Technologies
    with Zend Optimizer v3.3.3, Copyright (c) 1998-2007, by Zend Technologies


Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 247623
Server version: 5.0.45-log Source distribution

[root@ded1461 bin]# httpd -v
Server version: Apache/2.2.3
Server built:   Nov 12 2008 07:09:03


[root@ded1461 bin]# uname -a
Linux ded1461 2.6.18-92.el5 #1 SMP Tue Apr 29 13:16:15 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux
MOD: Bitte [noparse]
Code:
...
[/noparse]-Tags um Ausgaben, Code, etc. verwenden (im Editor auch mit '#' erreichbar). Danke!


Ich hoffe das reicht als Information.
 
Last edited by a moderator:
Zu GreenSQL kann ich sagen, dass die Performance relativ stark leidet. GreenSQL hilft auch nur gegen "böse" Abfragen, die man über unsichere Software einschleusen kann. Gegen Massenabfragen hilft das nicht.

Was sagt denn euer Webserver dazu? Den würde ich wohl noch vor der mySQL-Datenbank anschauen und gegen Überlast absichern.
 
Hallo,

richtig wir haben GreenSQL initialisiert um die Datenbankqueries for Injection besser schützen zu können und das scheint auch sehr gut zu funktionieren.

Wir hatten ModEvansive und ModSec im Einsatz. Das mussten wir aber wieder abschalten, weil wir feststellen mussten dass teilweise Google nicht mehr crawlen konnte oder auch Klienten die Seite nicht mehr besuchen konnten, weil diese dann sehr häufig den 403 Forbidden erhielten.

Code:
LoadModule evasive20_module   /usr/lib64/httpd/modules/mod_evasive20.so

<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   10
</IfModule>


 KeepAlive On
 KeepAliveTimeout 4
 MaxKeepAliveRequests 500
ServerLimit 60
 MaxClients 60
 StartServers 30
 MinSpareServers 30
 MaxSpareServers 30
 MaxRequestsPerChild 1000
 ServerTokens Prod
 ServerSignature On
 HostnameLookups Off
 
Wenn du bei normalem Browsen 403er kriegst, dann sind die Einstellungen zu limitierend.

Such mal hier im Forum, ich glaube hier gab es mal nen Thread der sich mit mod_evasive befasst. Vielleicht findest du da noch ein paar Tipps.

Performance ist ja nicht euer Problem, sondern er kann irgendwann keine Verbindung mehr herstellen, oder?

Von welchem Zeitpunkt ist der top-Auszug? Wenn der Server schon keine sinnvolle Antwort mehr gibt?

Blöde Frage, Festplattenspeicher habt ihr genug frei, oder?
 
Wir haben 2x160GB HDD im Raidverbund davon sind aktuell 36GB belegt.

Der Top-Auszug ist vor 30 Minuten, wenn ca.2500 User online sind und MySQL fast am abschmieren ist.

Richtig User erhalten einen 403 und Suchmaschinen können demnach auch nicht mehr crawlen. Deswegen mussten wir das rausnehmen.
 
Die Preisfrage ist, warum er erreichbar ist und dann irgendwann nicht mehr.

Ich nehme mal an, dass die Datenbanken alle unbeschädigt sind? Es kann demnach - da er unter Last Schwierigkeiten bekommt - doch fast nur an zu hohem Speicherverbrauch liegen, oder siehst du das anders?

Gibt es denn noch andere Log-Einträge, die im Zusammenhang mit diesem Problem stehen?

Ich würde mal testweise versuchen den RAM-Verbrauch von mySQL etwas zu reduzieren, so auf 4.5 GB insgesamt. Dann mal sehen ob es stabiler läuft.
 
Du hast es richtig erkannt, er schmiert ab wenn der RAM voll läuft und die LoadAverage auf über 18% geht.

MySQL verbraucht weniger RAM, die HTTPD Prozesse sind enorm. Wenn ich mir die TOP-Werte so anschaue.
 
...sehr viele Firmen versuchen unseren Content zu replizieren bzw. versuchen Massenanfragen an unseren Server...

Ist das gewollt?

...Wir hatten ModEvansive und ModSec im Einsatz...403 etc.

Wenn mod_security mit "403 Forbidden" verweigert, gibt es dafür einen Grund. Meist dann, wenn ganze Rulesets einfach kopiert werden und sich dann mit diversen Applikationen stechen. Auch muss jede einzelne Rule durchlaufen werden. Hier hilft ein Blick in das mod-sec-Logfile, warum ein 403 ausgelöst wurde.

mod_evasive kann durchaus bei einigen Applikationen, die viele parallele Prozesse öffen, zu "false Positive" führen.

max_connections = 500

Das ist ziemlich viel.

ServerLimit 60
MaxClients 60

Im Verhältnis zu den max_connections in mysql eher dünn angesiedelt.
Habt Ihr schon versucht, mysql im Speicher etwas zu beschneiden und dafür den Apache etwas mehr zu gönnen?

...weil wir feststellen mussten dass teilweise Google nicht mehr crawlen konnte...

Hm, Google und übereifrige Suchmaschinen wie Yahoo kann man auch beschneiden bzw. limitieren. Sowohl in der Bandbreite als auch in der Anzahl der gleichzeitigen SuchProzesse (wenn man es so nennen will) Mit mod_cband :D und auch mit mod_security. Yahoo zB. ist bei mir auf einen Netzbereich getrimmt, den seine Crawler benutzen dürfen, die Bandbreite regelt mod_cband. Der Rest wird für eine bestimmte Zeit durch mod_security per IP-Tables gesperrt. Suchmaschinen sind nicht blöd und auch nicht beleidigt.
 
Back
Top