it-swarm.asia

خطأ في إنشاء InnoDB: "حجم الصف كبير جدًا"

لدينا بعض المهندسين الذين يقومون بتسوية هيكل ديسيبل عادي في جدول مؤقت لأغراض إنشاء تقرير. الأعمدة محددة على أنها TEXT NOT NULL (أعرف "لماذا يفعلون ذلك؟" ، لنفترض أننا نتعامل مع هذا).

نستخدم MySQL 5.1.48 Community RHEL5 مع المكون الإضافي InnoDB 1.0.9 على Linux.

عند استخدام MyISAM ، لم نواجه أبدًا حدود حجم الجدول للحد الأقصى من الأعمدة أو الحد الأقصى لطول الصف (أثناء التحقيق ، وصلنا إلى الحد الأقصى للأعمدة عند 2598 (يتسبب 2599 في الخطأ 1117). مع InnoDB ، فإننا نصل إلى الحدود. تظهر هذه الحدود عند إنشاء جدول (بدون إدخال بيانات) على النحو التالي:

خطأ 1118 (42000) في السطر 1: حجم الصف كبير جدًا. الحد الأقصى لحجم الصف لنوع الجدول المستخدم ، دون احتساب BLOBs ، هو 8126. يجب تغيير بعض الأعمدة إلى TEXT أو BLOBs

أبحث عن إجابات لما يلي:

  1. ما هي الصيغة التفصيلية لتحديد تفاصيل حجم الصف عند استخدام أجزاء أعمدة v/v/b/t؟ لقد جربت بعض الصيغ المختلفة باستخدام أعمدة varchar(N) (حيث N بين 1 و 512) ، ومجموعة الأحرف UTF8 (* 3) ، وعدد الأعمدة التي سيستغرقها الجدول حتى الفشل. لم أجد أيًا من المجموعات التي جربتها تعطي قيمًا تتطابق مع نتائج الاختبار الفعلية.

  2. ما هي "النفقات العامة" الأخرى التي يجب مراعاتها عند حساب حجم الصف؟

  3. لماذا تتغير رسالة الخطأ من 8126 إلى 65535 عندما انتقل من إنشاء جداول بأعمدة varchar (109) إلى varchar (110) أعمدة؟

11
Evan

إجابات أسئلتك معقدة ، لأنها تختلف باختلاف InnoDB تنسيق الملف . يوجد اليوم تنسيقات تسمى Antelope و Barracuda.

يكون ملف مساحة الجدول المركزي (ibdata1) دائمًا بتنسيق Antelope . إذا كنت تستخدم الملف لكل جدول ، فيمكنك جعل الملفات الفردية تستخدم Barracuda التنسيق عن طريق تعيين innodb_file_format=Barracuda في my.cnf.

النقاط الأساسية:

  • يجب أن تحتوي صفحة 16 كيلوبايت واحدة من بيانات InnoDB على صفين من البيانات على الأقل. بالإضافة إلى أن كل صفحة تحتوي على رأس وتذييل يحتوي على المجموع الاختباري للصفحة ورقم تسلسل السجل وما إلى ذلك. هذا هو المكان الذي تحصل فيه على حد أقل قليلاً من 8 كيلو بايت لكل صف.

  • يتم تخزين أنواع البيانات الثابتة مثل INTEGER و DATE و FLOAT و CHAR في صفحة البيانات الأساسية هذه ويتم حسابها ضمن حد حجم الصف.

  • يتم تخزين أنواع البيانات ذات الحجم المتغير مثل VARCHAR و TEXT و BLOB على الصفحات الفائضة ، لذلك لا يتم احتسابها بالكامل في حدود حجم الصف. في Antelope ، يتم تخزين ما يصل إلى 768 بايت من هذه الأعمدة في صفحة البيانات الأساسية بالإضافة إلى تخزينها في صفحة التدفق. يدعم Barracuda تنسيق الصف الديناميكي ، لذلك قد يقوم بتخزين مؤشر 20 بايت فقط على صفحة البيانات الأساسية.

  • كما تُسبَق أنواع البيانات ذات الحجم المتغير ببايت واحد أو أكثر لترميز الطول. كما يحتوي تنسيق صف InnoDB أيضًا على مجموعة من الإزاحات الميدانية. إذن هناك بنية داخلية أكثر أو أقل موثقة في ويكي . [EDIT] رابط معطل - هنا يبدو أفضل الآن.

يدعم Barracuda أيضًا ROW_FORMAT = COMPRESSED للحصول على مزيد من كفاءة التخزين لبيانات الفائض.

يجب أن أعلق أيضًا على أنني لم أر أبدًا جدولًا مصممًا جيدًا يتجاوز حد حجم الصف. إنها "رائحة كود" قوية أنك تنتهك مجموعات مكررة حالة النموذج العادي الأول.

19
Bill Karwin

موقفي مختلف قليلاً. من المحتمل أن يكون أحد عناصر البيانات التي أحتاج إلى تخزينها في كل صف كبيرًا جدًا. (حقل البيانات هو LONGBLOB لمستند قد يحتوي على صور مضمنة متعددة. تحتوي قاعدة البيانات النموذجية على مستندات بحجم 25-30 ميجابايت ، ولكن هذه المستندات قد تكون أكبر في بعض الحالات.) . (تغيير نوع ملف InnoDB إلى Barracuda ، وزيادة حجم ملف السجل ، وتعيين تنسيق الصف إلى COMPRESSED.)

كان الحل الوحيد الذي وجدته والذي نجح معي هو العودة إلى MySQL 5.5.x من MySQL 5.6.x.

1
David