{"id":101,"date":"2007-12-20T10:08:57","date_gmt":"2007-12-20T08:08:57","guid":{"rendered":"http:\/\/robert.kolatzek.org\/wblog\/?p=101"},"modified":"2007-12-20T10:08:57","modified_gmt":"2007-12-20T08:08:57","slug":"umstieg_innodb","status":"publish","type":"post","link":"https:\/\/blog.kolatzek.org\/wblog\/101\/umstieg_innodb","title":{"rendered":"Der Umstieg auf InnoDB"},"content":{"rendered":"<p>Man h\u00f6rt hier und da, InnoDB als Storage Engine f\u00fcr MySQL w\u00e4re besser. Nur was bedeutet besser? Schneller? Speicher schohnender?<\/p>\n<p>Der gr\u00f6\u00dfte Vorteil von InnoDB (\u00fcbernommen von Oracle, aber GPL 2 lizensiert) sind die sog. row-locks, die nur eine einzige Zeile einer Datenbanktabelle sperren, statt gleich die ganze Tabelle unzug\u00e4nglich zu machen. Transactions kann man auch mit MyISAM haben (nur eben ohne row-lock). Ich wei\u00df zwar nicht genau, ob MyISAM auch ACID transactions gerantiert, aber ich kann mir kaum vorstellen, dass es nicht so ist.<\/p>\n<p>Der Weg zu InnoDB kann manchmal richtig hard sein&#8230; Man muss vieles beachten: von I\/O im Betriebssystem bis hin zu \u00dcberpr\u00fcfung aller Skripte, die auf MySQL zugreifen.<br \/>\n<!--more--><\/p>\n<p>Wenn man an eine Umstellung auf InnoDB denkt, muss man als erstes sehr kritisch mit sich selbst umgehen. Ist meine Datenbank-Architektur \u00fcberhaupt auf einem Level, den man die 3. Normalform nennt? Oder schreibe ich in die Spalten jeden Sch..ss und versuche mit &#8222;%etwas%&#8220; eine Information heruaszufinden? Sind die Zeilen-Werte m\u00f6glichst eindeutig und als Relationen zwischen verschiedenen Tabellen zu benutzten? Oder ist alles in einer Monstertabelle? Sind nur die n\u00f6tigen Indexe angelegt oder l\u00e4sst man einfach alles indexieren? Sollte ich nicht besser Sphinx betreiben, statt in FULLTEXT-Indexen herumzukramen?<\/p>\n<p>By the way: FULLTEXT gibt es in InnoDB nicht. Also l\u00f6schen! Danach &#8211; oder noch besser zuvor &#8211; die Skripte nach &#8222;MATCH &#8230; AGAINST&#8220; durchsuchen. Diese SQL-Statements ben\u00f6tigen die Volltext-Indexe. Und wo wir gerade dabei sind, unsere Skripte anzuschauen: gibt es da eine M\u00f6glichkeit, gleich nach der Auswahl der Datenbank ein einfaches SQL &#8222;BEGIN&#8220; und am Ende des Ablaufs ein SQL &#8222;COMMIT&#8220; abzusetzen? Wenn man &#8222;SET AUTOCOMMIT=0&#8220; benutzt (noch vor &#8222;BEGIN&#8220;), kann MySQL erst einmal unsere &#8222;W\u00fcnsche&#8220; auf den Wunschzettel schreiben, so tun, als h\u00e4tte sie es erf\u00fcllt, und erst am Ende (bei &#8222;COMMIT&#8220;) Alles in einem Rutsch ausf\u00fchren oder (bei &#8222;ROLLBACK&#8220;) zur\u00fccknehmen. Mit AUTOCOMMIT gibt es keinen Wunschzettel&#8230; Alles wird direkt in die Tabellen reingeschrieben! Vorteil gegen\u00fcber MyISAM ist gleich NULL! Vor allem bei unvorhersehbaren Updates (z.B. 2x Update von denselben Zeilen auf dieselben Werte) w\u00fcrde unser Wunsch-Update mit BEGIN-COMMIT nur einmal in die Datenbank geschrieben&#8230; und das spart Zeit!<\/p>\n<p>Man sollte sich unbedingt die Beschreibung von <a href=\"http:\/\/dev.mysql.com\/doc\/refman\/5.1\/de\/innodb-restrictions.html\">Beschr\u00e4nkungen in InnoDB<\/a> als Bett-Lekt\u00fcre zu Gem\u00fcte f\u00fchren. Vor allem die Abschnitte \u00fcber schwachsinnige COUNT&#8217;s ohne WHERE Bedingungen, die 2 GB Grenze bei Dateien (wohl eher Vergangenheit wie Linuxkernel 2.4 und ext2), das AUTO_INCREMENT und Tabellen-LOCK&#8217;s. Dass eine Tabelle nicht mehr als 1000 Spalten haben sollte oder eine Zeile die 4GB-Grenze nicht \u00fcberschreiten darf ist ja wohl klar (keine Monstertabelen!). Auch VARCHAR-Spalten d\u00fcrfen zusammen nicht mehr als 65535 Zeichen haben (das entspricht z.B. 256 Spalten a 256 Zeichen).<\/p>\n<p>Wenn das alles einigerma\u00dfen zutrifft, kann man sich der Einrichtung von InnoDB in my.cnf bzw. my.ini zuwenden. Der erste und entscheidende Wert f\u00fcr InnoDB ist: &#8222;<strong>innodb_buffer_pool_size<\/strong>&#8222;. Man sollte ihn wie folgt berechnen<br \/>\n<span style=\"font-family: Courier New\"><br \/>\nkey_buffer + (max_connections * (sort_buffer_size+read_buffer_size+binlog_cache_size)) + <\/span><span style=\"font-family: Courier New\">max_connections * 2<\/span><\/p>\n<p>bedeutet: 1024+ (256*(2)) + 256*2 = 2048 also 2048 MB RAM sollte f\u00fcr InnoDB von MySQL freigehalten werden, wenn man den key_buffer so hoch und die maximale Zahl der Verbindungen mit 256 beziffert (eher selten anzutreffen). Hier sto\u00dfen wir auf die erste Grenze: 2 GB RAM f\u00fcr ein userprocess &#8211; das ist viel (bei 32 bit). Wenn man noch h\u00f6her gehen will, sollte man mehr als 4 GB RAM haben, und CONFIG_X86_4G=y, CONFIG_HIGHMEM64G=y, CONFIG_HIGHMEM=y, CONFIG_X86_PAE=y, CONFIG_HIGHMEM64G=y in den kernel einkompilieren. Vor allem 32 bit Systeme k\u00f6nnen schnell abst\u00fcrzen, wenn der Speicher nicht reicht! Die 64-Bitter sehen das etwas entspannter. Man sollte <strong>innodb_buffer_pool_size <\/strong>hoch ansetzen: 50, allerh\u00f6chstens aber 80% des verf\u00fcgbaren RAM (wenn ausser MySQL sonst auf dem Rechner nichts l\u00e4uft). Mit <strong>innodb_additional_mem_pool_size<\/strong> kann man noch etwas Puffer einr\u00e4umen &#8211; aber nicht zu viel! <a href=\"http:\/\/mysqldatabaseadministration.blogspot.com\/2007\/04\/innodb-performance-optimization.html\">Farhan Mashraqi<\/a> empfiehlt 10 MB.<\/p>\n<p>Als n\u00e4chstes sind die Log-Dateien dran. <strong>innodb_log_file_size<\/strong> entscheidet unter anderem, wie oft wirklich in die Tabelle geschrieben wird. Ist sie gro\u00df (so gro\u00df wie innodb_buffer_pool_size, aber kleiner als 4 GB) kann das der MySQL bei Zugriffs-Spitzen etwas Spielraum einr\u00e4umen.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Man h\u00f6rt hier und da, InnoDB als Storage Engine f\u00fcr MySQL w\u00e4re besser. Nur was bedeutet besser? Schneller? Speicher schohnender? Der gr\u00f6\u00dfte Vorteil von InnoDB (\u00fcbernommen von Oracle, aber GPL 2 lizensiert) sind die sog. row-locks, die nur eine einzige Zeile einer Datenbanktabelle sperren, statt gleich die ganze Tabelle unzug\u00e4nglich zu machen. Transactions kann man [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[8],"tags":[65,74,96],"class_list":["post-101","post","type-post","status-publish","format-standard","hentry","category-software","tag-linux","tag-opensource","tag-server","entry"],"_links":{"self":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts\/101","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/comments?post=101"}],"version-history":[{"count":0,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/posts\/101\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/media?parent=101"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/categories?post=101"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.kolatzek.org\/wblog\/wp-json\/wp\/v2\/tags?post=101"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}