khounlivong
Occasional Observer

Deadlocks und Integration-Module

Jump to solution

Wir benutzen das u.a. DynamicDatabaseAccess-Module (FSIntegration) und haben intensiven Zugriff durch unsere Redakteure. In der nahen Vergangenheit hatten wir sowohl Probleme mit der Datenbank-Connectivität als auch mit der Thread-Anzahl des Systemes. Der Datenbank-Server liegt zentral und bedient content-mäßig sowohl das CMS als auch unsere Frontend.

Hinweisen folgend haben wir sowohl die Threadzahl erhöht (conf/fs-webapp.xml) als auch die MySQL-Parameter entsprechend Doku angepaßt:

jdbc.POOLCYCLE=60

jdbc.POOLMAX=1

jdbc.POOLMIN=1

jdbc.POOLTIMEOUT=180

Jetzt erhalten wir Deadlock-Exceptions in den Clients beim Speichern und Löschen (.doStore, .doDelete), zu den eingestellten Save/NotSaved-Seiten kommt das System in dem Fall gar nicht. Die Vorgaben für die DB sind default:

mysql> show variables like "%inno%";
+-----------------------------------------+------------------------+
| Variable_name                           | Value                  |
+-----------------------------------------+------------------------+
| have_innodb                             | YES                    |
| ignore_builtin_innodb                   | OFF                    |
| innodb_adaptive_hash_index              | ON                     |
| innodb_additional_mem_pool_size         | 1048576                |
| innodb_autoextend_increment             | 8                      |
| innodb_autoinc_lock_mode                | 1                      |
| innodb_buffer_pool_size                 | 8388608                |
| innodb_checksums                        | ON                     |
| innodb_commit_concurrency               | 0                      |
| innodb_concurrency_tickets              | 500                    |
| innodb_data_file_path                   | ibdata1:10M:autoextend |
| innodb_data_home_dir                    |                        |
| innodb_doublewrite                      | ON                     |
| innodb_fast_shutdown                    | 1                      |
| innodb_file_io_threads                  | 4                      |
| innodb_file_per_table                   | OFF                    |
| innodb_flush_log_at_trx_commit          | 1                      |
| innodb_flush_method                     |                        |
| innodb_force_recovery                   | 0                      |
| innodb_lock_wait_timeout                | 50                     |
| innodb_locks_unsafe_for_binlog          | OFF                    |
| innodb_log_buffer_size                  | 1048576                |
| innodb_log_file_size                    | 5242880                |
| innodb_log_files_in_group               | 2                      |
| innodb_log_group_home_dir               | ./                     |
| innodb_max_dirty_pages_pct              | 90                     |
| innodb_max_purge_lag                    | 0                      |
| innodb_mirrored_log_groups              | 1                      |
| innodb_open_files                       | 300                    |
| innodb_rollback_on_timeout              | OFF                    |
| innodb_stats_method                     | nulls_equal            |
| innodb_stats_on_metadata                | ON                     |
| innodb_support_xa                       | ON                     |
| innodb_sync_spin_loops                  | 20                     |
| innodb_table_locks                      | ON                     |
| innodb_thread_concurrency               | 8                      |
| innodb_thread_sleep_delay               | 10000                  |
| innodb_use_legacy_cardinality_algorithm | ON                     |
+-----------------------------------------+------------------------+
38 rows in set (0.00 sec)

Irgendeine Idee, wie man das Debuggen kann?

Die fs-server.log enthält als einzigen Hinweis innerhalb der Exception:

java.sql.SQLException: Deadlock found when trying to get lock; try restarting transaction

0 Kudos
1 Solution

Accepted Solutions
klein
Crownpeak employee

Hi Ninji,

wie besprochen, lassen sich die Parameter für die JDBC-Connections schwer vorher bestimmen.

Denn es gibt nicht zwei gleiche FS-Projekte Smiley Sad
In jedem Projekt werden unterschiedliche Anzahl von Schemata, Tabellen, Fremdschlüsselbeziehungen verwendet (dazu kommen noch unterschiedliche Tabelleninhalte/Größe, Abfragen, DB-Typ wie MySQL/Oracle, Frequenz der Abfragen / der Schreiboperationen, etc.).

Die Anzahl der Connections hängt auch sehr von der Art und der Intensität der Nutzung von diesen Connections und daher kann man hier sehr schwierig irgendwelche Werte empfehlen zumal bei euch noch das Integration-Modul benutzt wird, welches von dem LIVE-System auf die gleiche DB zugreift

Eure MySQL-Settings lauten:

===============================

mysql> show variables like "%timeout%";

+----------------------------+-------+

| Variable_name              | Value |

+----------------------------+-------+

| connect_timeout            | 10    |

| delayed_insert_timeout     | 300   |

| innodb_lock_wait_timeout   | 50    |

| innodb_rollback_on_timeout | OFF   |

| interactive_timeout        | 28800 |

| net_read_timeout           | 30    |

| net_write_timeout          | 60    |

| slave_net_timeout          | 3600  |

| table_lock_wait_timeout    | 50    |

| wait_timeout               | 28800 |

+----------------------------+-------+

===============================

Daher haben wir so eben diese Werte gesetzt:

-------------------------------------

jdbc.POOLMAX    = 15

jdbc.POOLTIMEOUT = 180

jdbc.POOLMIN    = 10

jdbc.POOLCYCLE = 120

-------------------------------------

und werden nu beobachten, ob sich die Performance gebessert hat.

Gruß,

Walter.

View solution in original post

0 Kudos
6 Replies
thmarx
I'm new here

Hallo,

ich bin jetzt keine Datenbankspezialist, allerdings kommt mir die Einstellung:

jdbc.POOLMAX=1

jdbc.POOLMIN=1

etwas komisch vor.

Sie Erzeugen damit einem ConnectionPool mit genau einer Connection. Das bedeutet, alle Datenbankzugriffe laufen über diese eine Connection.

Versuchen sie es doch einmal mit hören Werten:

jdbc.POOLMAX=15

jdbc.POOLMIN=10

Evtl. können auch höhere Werte von Vorteil sein.

Viele Grüße

Thorsten Marx

0 Kudos

Hallo,

die Werte wurden mit dem Support abgesprochen und das Ergebnis eines vorherigen Tunings. Sie sind auch so in der Doku für DynamicDatabaseAccess hinterlegt. Wir haben auch mit höheren Werten experimentiert ohne daß es zu einer Verbesserung kam. So wie ich das verstehe wird eine Verbindung benutzt und sofort wieder abgegeben. Das sollte die Wartezeit der wartenden Requests reduzieren.

Wie nun ein Deadlock auf die InnoDB zustandekommt ist AFAIK davon unbeeindruckt. Wir denken eher, daß es hier zu einem vollständigen Table-Lock kommt oder aber ein Prozeß sich selbst blockiert. Die Idee wäre, einen Reuse zu realisieren. Dazu müssen wir aber wissen, wie genau doStore/doDelete vorgeht.

0 Kudos

Khamsonh M. Khounlivong wrote:

Hallo,

die Werte wurden mit dem Support abgesprochen und das Ergebnis eines vorherigen

mit welchem Support?

0 Kudos
Peter_Jodeleit
Crownpeak employee

Die Fehlermeldung von MySQL besagt, das die Transaktion des Benutzers mit einer Transaktion eines anderen Benutzers konfliktär ist. Und das dieser Konflikt nicht automatisch aufgelöst werden kann.

Umfasst eine Transaktion viele Datensätze? Oder werden wenige Datensätze von vielen Sessions gleichzeitig verändert?

Zu

> jdbc.POOLMAX=1

> jdbc.POOLMIN=1

Diese Einstellung bedeutet, das genau eine JDBC-Verbindung im Pool verbleibt. Sobald diese belegt ist, werden neue Verbindungen geöffnet. Gut ist das nicht.

Peter
0 Kudos
klein
Crownpeak employee

Hi Ninji,

wie besprochen, lassen sich die Parameter für die JDBC-Connections schwer vorher bestimmen.

Denn es gibt nicht zwei gleiche FS-Projekte Smiley Sad
In jedem Projekt werden unterschiedliche Anzahl von Schemata, Tabellen, Fremdschlüsselbeziehungen verwendet (dazu kommen noch unterschiedliche Tabelleninhalte/Größe, Abfragen, DB-Typ wie MySQL/Oracle, Frequenz der Abfragen / der Schreiboperationen, etc.).

Die Anzahl der Connections hängt auch sehr von der Art und der Intensität der Nutzung von diesen Connections und daher kann man hier sehr schwierig irgendwelche Werte empfehlen zumal bei euch noch das Integration-Modul benutzt wird, welches von dem LIVE-System auf die gleiche DB zugreift

Eure MySQL-Settings lauten:

===============================

mysql> show variables like "%timeout%";

+----------------------------+-------+

| Variable_name              | Value |

+----------------------------+-------+

| connect_timeout            | 10    |

| delayed_insert_timeout     | 300   |

| innodb_lock_wait_timeout   | 50    |

| innodb_rollback_on_timeout | OFF   |

| interactive_timeout        | 28800 |

| net_read_timeout           | 30    |

| net_write_timeout          | 60    |

| slave_net_timeout          | 3600  |

| table_lock_wait_timeout    | 50    |

| wait_timeout               | 28800 |

+----------------------------+-------+

===============================

Daher haben wir so eben diese Werte gesetzt:

-------------------------------------

jdbc.POOLMAX    = 15

jdbc.POOLTIMEOUT = 180

jdbc.POOLMIN    = 10

jdbc.POOLCYCLE = 120

-------------------------------------

und werden nu beobachten, ob sich die Performance gebessert hat.

Gruß,

Walter.

0 Kudos
khounlivong
Occasional Observer

Ja, die Anpassung habe ich verstanden und auch noch verfeinert. Jetzt mit größerem Pool finden auch weniger Thread-Staus statt. Daß wir dabei die nicht abgefangene ORException entdeckt haben, war wohl eher Zufall und wir haben das ja an dei Entwicklungsabteilung weitergegeben.

Freuen wir uns auf ein verbessertes DynamicDatabaseAccess-Modul und Danke!

0 Kudos