[前][次][番号順一覧][スレッド一覧]

mysql:12775

From: Tetsuro IKEDA <Tetsuro IKEDA <tetsuro@xxxxxxxxxx>>
Date: Sat, 18 Feb 2006 02:10:03 -0500
Subject: [mysql 12775] Re: Mysql JDBC接続時のサイズ制限

池田です。

InnoDBのPageサイズを大きくすることで1行辺りのデータサイズの制限を
緩和する件ですが、仕組みを調べてみようとソースコードを読んでいましたところ、
以下のような記述を見つけました。

MySQL 4.0.21 innobase/include/rem0rec.h

/* The data size of record must be smaller than this because we reserve
two upmost bits in a two byte offset for special purposes */
#define REC_MAX_DATA_SIZE	(16 * 1024)

この定数なのですが、InnoDBが行サイズを計算するのに使用していると思われる
btr_cur_optimistic_insert関数(innobase/btr/btr0cur.c)にて使用されています。

この関数のロジックを読んでみると、どうもこの定数を超える場合には
"Got error 139 from table handler"のエラー処理を行うように思えました。

つまりPageサイズを64KBまで拡張したとしても、1行辺りのデータサイズは16KB
までしか扱えないのではないかということです。

これを確かめるべく、Pageサイズを64KBに拡張したMySQL 4.0.21にて、以下の
SQL文を実行してみましたところ、やはり16KBを超えたところで
"Got error 139 from table handler"のエラーが返るようになりました。

create table t1 (c1 blob, c2 blob, c3 blob, c4 blob, c5 blob, c6 blob, c7 blob, c8 blob,
c9 blob, c10 blob, c11 blob, c12 blob, c13 blob, c14 blob, c15 blob, c16 blob, c17 blob,
c18 blob, c19 blob, c20 blob, c21 blob, c22 blob, c23 blob, c24 blob, c25 blob, c26 blob,
c27 blob, c28 blob, c29 blob, c30 blob, c31 blob, c32 blob, c33 blob, c34 blob, c35 blob,
c36 blob, c37 blob, c38 blob, c39 blob, c40 blob, c41 blob, c42 blob, c43 blob, c44 blob,
c45 blob, c46 blob, c47 blob, c48 blob, c49 blob, c50 blob, c51 blob, c52 blob, c53 blob,
c54 blob, c55 blob, c56 blob, c57 blob, c58 blob, c59 blob, c60 blob, c61 blob, c62 blob,
c63 blob, c64 blob, c65 blob) type=innodb;

insert into t1 set c1=repeat('A', 512);

update t1 set c2=c1, c3=c1, c4=c1, c5=c1, c6=c1, c7=c1, c8=c1, c9=c1, c10=c1, c11=c1,
c12=c1, c13=c1, c14=c1, c15=c1;

まずこれで 512*15=7680バイトを格納します。

update t1 set c16=c1;

これで8192バイトとなり、8000バイト超となりますがPageサイズが拡張されているためエラーになり
ません。

update t1 set c17=c1, c18=c1, c19=c1, c20=c1, c21=c1, c22=c1, c23=c1, c24=c1, c25=c1,
c26=c1, c27=c1, c28=c1, c29=c1, c30=c1, c31=c1;

さらにこれで合計 512*31=15872バイトを格納します。ここまではOKです。しかし、

update t1 set c32=c1;
ERROR 1030: Got error 139 from table handler

16KBに達したところでこのエラーとなってしまいました。
この新たに判明した16KB制限でありますが、現在のInnoDBの行構造を改造でも
しない限り、増やすことは難しいと思います。

以上、ご参考まで。


Tetsuro IKEDA wrote:
> 池田です。こちらの手元のマシンで動作確認を完了しました。
> 
> innobase/include/univ.i ファイルを以下のように変更することで、
> 何通か前に送ったメールではエラーとなっていたものを、
> エラー無しにUPDATEすることができました。
> 
> 
>>64KBの場合、
>>
>>UNIV_PAGE_SIZE = 8 * 8192
>>UNIV_PAGE_SIZE_SHIFT = 16
>>
> 
> 
> 【注意点】
> この変更を行うと、InnoDBのデータファイル、ログファイル、ログバッファなどの
> 設定値がデフォルトのままでは起動しなくなります。
> Pageサイズが4倍になっているので、その影響だと思われます。
> 
> 例えば、以下のように十分な値を設定する必要があります。
> 
> --innodb_data_home_dir=
> --innodb_data_file_path=/foobar/ibdata1:100M:autoextend
> --innodb_log_file_size=50M
> --innodb_buffer_pool_size=200M
> 
> Tetsuro IKEDA wrote:
> 
>>池田@自己レスです。
>>
>>ちゃんとコメント読め、という感じでした(^^;
>>
>>・UNIV_PAGE_SIZE には2の累乗を設定する
>>・UNIV_PAGE_SIZE_SHIFT にはUNIV_PAGE_SIZEのその2の対数を設定する
>>
>>ということですね。
>>
>>つまりPageサイズには48KBのようなサイズは指定できないということですね。
>>
>>64KBの場合、
>>
>>UNIV_PAGE_SIZE = 8 * 8192
>>UNIV_PAGE_SIZE_SHIFT = 16
>>
>>ということになるでしょうか。
>>
>>Tetsuro IKEDA wrote:
>>
>>
>>>池田です。
>>>
>>>InnoDBのPageサイズを変えるためには、ソースファイルを直接編集した後に、
>>>コンパイルする必要があるようです。
>>>
>>>【変更対象】
>>>$MySQL/innobase/include/univ.i
>>>・UNIV_PAGE_SIZE
>>>・UNIV_PAGE_SIZE_SHIFT
>>>
>>>【参考】
>>>http://dev.mysql.com/doc/refman/4.1/en/innodb-restrictions.html
>>>
>>>例えばPageサイズを64KBにする場合、UNIV_PAGE_SIZEを"8 * 8192"に変えるのは
>>>良いとして、UNIV_PAGE_SIZE_SHIFTはどう変更するのがいいんでしょうかね。
>>>
>>>考え中・・・。もし分かったら教えてください(^^)
>>>
>>>kyou tech wrote:
>>>
>>>
>>>
>>>>だいぶ解ったような気がします。丁寧なご説明に感動しました。
>>>>mysqlの醍醐味も感じ始めています。
>>>>
>>>>
>>>>
>>>>
>>>>>2.コンパイルオプションを指定してInnoDBのPageサイズをデフォルトの16KBか
>>>>
>>>>ら、
>>>>
>>>>
>>>>
>>>>
>>>>>  もっと大きな値にする(最大で64KBまで指定可能)。
>>>>>  (64KBにすることで制限は8KBから32KBに緩和される。)
>>>>
>>>>で試したいと思います。
>>>>ただ、configure --helpで見るとpage sizeのオプションがないようですが、
>>>>直接configureファイルを修正することになるでしょうか。
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>From: Tetsuro IKEDA <tetsuro@xxxxxxxxxx>
>>>>>Reply-To: ml@xxxxxxxxxx
>>>>>To: ml@xxxxxxxxxx
>>>>>Subject: [mysql 12769] Re: Mysql JDBC接続時のサイズ制限
>>>>>Date: Thu, 16 Feb 2006 22:04:00 -0500
>>>>>
>>>>>池田@Connector/Jチームにてインターン中です。
>>>>>
>>>>>まず確認したいのですが、使用しているストレージエンジンはInnoDBで宜しいで
>>>>
>>>>しょうか?
>>>>
>>>>
>>>>
>>>>
>>>>>さて、InnoDB前提で考えた場合、ちょっと説明が長くなりますが、以下私の予 
>>>>>想で
>>>>
>>>>す。
>>>>
>>>>
>>>>
>>>>
>>>>>【InnoDBにおける行サイズのデフォルトの最大値(約8000バイト)を超えたのが原
>>>>
>>>>因】
>>>>
>>>>
>>>>
>>>>
>>>>>InnoDBはテーブルのデータを格納する領域であるTable Spaceを、デフォルトでは
>>>>
>>>>16KB
>>>>
>>>>
>>>>
>>>>
>>>>>(これはコンパイル時に指定されます)のPage単位に分割して管理しており、
>>>>>それぞれのPage内に各行を"主キーでソートした状態"で格納しています。
>>>>>(InnoDBにおけるClustered Index)
>>>>>
>>>>>これに関連して、InnoDBでは各行の最大長はPageサイズの半分以下であるこ 
>>>>>と、と
>>>>
>>>>いう
>>>>
>>>>
>>>>
>>>>
>>>>>制限があります。デフォルトのPageサイズ16KBにおいては、8KBがこれに当たりま
>>>>
>>>>す。
>>>>
>>>>
>>>>
>>>>
>>>>>しかしInnoDBでは、InnoDBではTEXT(LONGTEXT)やBLOB(LONGBLOB)を使用する
>>>>
>>>>と、
>>>>
>>>>
>>>>
>>>>
>>>>>該当データをその行が可能されているPageの外に格納することができるため、
>>>>>実際には最大4GBまでの行を格納することができます。
>>>>>
>>>>>ただし、例えば以下のDDLがあり、
>>>>>
>>>>>CREATE TABLE t1 (c1 TEXT) TYPE=InnoDB;
>>>>>
>>>>>以下のDMLが実行されたとすると、
>>>>>
>>>>>INSERT INTO t1 SET c1 = REPEAT('A', 10000);
>>>>>
>>>>>行が格納されているPageにはカラムc1の先頭512バイトが格納され、
>>>>>Page外に格納されるのは、残りの10000-512=9488バイトとなります。
>>>>>
>>>>>すなわち、この残りの9488バイトについては何も問題は無いのですが、
>>>>>先頭512バイト分については行が格納されているPage内に格納されるため、
>>>>>例えばこのc1のようなカラムが複数存在する場合には、Page内に合計で
>>>>>格納されるデータサイズが8000バイトを超えてしまい、今回生じているような、
>>>>>
>>>>>Got error 139 from table handler
>>>>>
>>>>>というエラーがInnoDBから投げられてしまうということになります。
>>>>>
>>>>>例えば以下のようなDDLおよびDMLを実行してみると分かりやすいでしょう。
>>>>>
>>>>>mysql> create table many_text(a text, b text, c text, d text, e text, f 
>>>>
>>>>text, g
>>>>
>>>>
>>>>
>>>>
>>>>>text, h text, i text, j text, k text, l text, m text, n text, o text, p 
>>>>
>>>>text)
>>>>
>>>>
>>>>
>>>>
>>>>>type=innodb;
>>>>>
>>>>>mysql> insert into many_text set a = repeat('.', 512);
>>>>>
>>>>>mysql> update many_text set
>>>>>b=a,c=a,d=a,e=a,f=e,g=a,h=a,i=a,j=a,k=a,l=a,m=a,n=a,o=a;
>>>>>
>>>>>mysql> update many_text set
>>>>>b=a,c=a,d=a,e=a,f=e,g=a,h=a,i=a,j=a,k=a,l=a,m=a,n=a,o=a,p=a;
>>>>>ERROR 1030: Got error 139 from table handler
>>>>>
>>>>>となると、今回の問題の回避方法ですが、以下の2つのどちらかではないかと 
>>>>>思われ
>>>>
>>>>ます。
>>>>
>>>>
>>>>
>>>>
>>>>>1.DDLを変更して8000バイト以上のデータがPage内に入らないようにする。
>>>>>  例:テーブルを分割する、行を統合するなど
>>>>>
>>>>>2.コンパイルオプションを指定してInnoDBのPageサイズをデフォルトの16KBか
>>>>
>>>>ら、
>>>>
>>>>
>>>>
>>>>
>>>>>  もっと大きな値にする(最大で64KBまで指定可能)。
>>>>>  (64KBにすることで制限は8KBから32KBに緩和される。)
>>>>>
>>>>>以上です。
>>>>>
>>>>>皆様、何か補足などありましたら宜しくお願いいたします。
>>>>>
>>>>>kyou tech wrote:
>>>>>
>>>>>
>>>>>
>>>>>>池田さん
>>>>>>
>>>>>>ご返事ありがとうございます。
>>>>>>対象テーブルは130項目があって、50項目ぐらいはTEXT型です。
>>>>>>中でfull size10000Byte項目が一個、5000Byte、3000Byte項目が若干ありま 
>>>>>
>>>>>す。
>>>>
>>>>
>>>>>>full sizeのレコード長は105KBぐらいです。
>>>>>>もともとMysqlのTextの上限は65535Byteと認識していますから、
>>>>>>個々のフィールドの制限違反よりは、
>>>>>>Mysql(4.0.21)の行のサイズに制限があるような感じしています。
>>>>>>本当にそうでしょうか。もしそうであれば、どこかの設定を修正するか(そう
>>>>>>願って
>>>>>>います)、
>>>>>>まさかテーブル分割することになるでしょうか。
>>>>>>今回始めてMysqlを使うことで、無知な質問ばかりですみません。
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>From: Tetsuro IKEDA <tetsuro@xxxxxxxxxx>
>>>>>>>Reply-To: ml@xxxxxxxxxx
>>>>>>>To: ml@xxxxxxxxxx
>>>>>>>Subject: [mysql 12767] Re: Mysql JDBC接続時のサイズ制限
>>>>>>>Date: Thu, 16 Feb 2006 07:07:24 -0500
>>>>>>>
>>>>>>>池田です。
>>>>>>>
>>>>>>>Connector/J(MySQL JDBC Type4 Driver)でStatementあるいはClient-Sideの
>>>>>>>PreparedStatementを使用する場合の送信可能なクエリの最大長は2GBです。
>>>>>>>(普通はそれよりも先にJVMのHEAPサイズが事実上の制限になると思います)
>>>>>>>
>>>>>>>Connector/Jに限らず、MySQLの全ての種類のクライアントは16MBを超える 
>>>>>
>>>>>SQL文
>>>>
>>>>に
>>>>
>>>>
>>>>
>>>>
>>>>>>>ついては、複数のPacketに分割してサーバへ送信します。
>>>>>>>max_allowed_packetは20MBに設定しているということですので、
>>>>>>>これが原因ということも無いと思います。
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>|java.sql.SQLException: Got error 139 from table handler
>>>>>>>
>>>>>>>こちらのエラーをPerrorで見るに、
>>>>>>>
>>>>>>>D:\mysql\mysql-4.0.26-win32\bin>perror 139
>>>>>>>MySQL error:  139 = Too big row
>>>>>>>
>>>>>>>これはConnector/Jが作成したエラーではなく、
>>>>>>>サーバから"Too big row"というメッセージでエラーが返ってきたことを意味
>>>>>>>してい
>>>>>>
>>>>>>ます。
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>何か思い当たる節はありませんか?
>>>>>>>
>>>>>>>kyou tech wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>>質問内容曖昧ですみません。
>>>>>>>>実は
>>>>>>>>画面上の各項目をfull sizeで入力して登録すると
>>>>>>>>下記のエラーが発生しています。
>>>>>>>>各項目を小さいサイズで入力するとうまく登録できます。
>>>>>>>>full sizeでのレコードの長さ:100KB
>>>>>>>>一応mysql server(4.0.21) の
>>>>>>>>max_allowed_packet
>>>>>>>>max_heap_table_sizeをそれぞれ20MBと32MBに調整したが、
>>>>>>>>同じくエラーが出ていますので、
>>>>>>>>jdbcのクエリーの長さに制限があるかと思っています。
>>>>>>>>ご教授いただければ助かります。
>>>>>>>>
>>>>>>>>|java.sql.SQLException: Got error 139 from table handler
>>>>>>>>|       at 
>>>>
>>>>com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2921)
>>>>
>>>>
>>>>
>>>>
>>>>>>>>|       at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1570)
>>>>>>>>|       at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
>>>>>>>>|       at com.mysql.jdbc.Connection.execSQL(Connection.java:2978)
>>>>>>>>|       at com.mysql.jdbc.Connection.execSQL(Connection.java:2902)
>>>>>>>>|       at
>>>>>>>>
>>>>
>>>>com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.ja
>>>>
>>>>
>>>>
>>>>
>>>>>>>>va:930)
>>>>>>>>|       at
>>>>>>>>
>>>>
>>>>com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
>>>>
>>>>
>>>>
>>>>
>>>>>>>>:1159)
>>>>>>>>|       at
>>>>>>>>
>>>>
>>>>com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
>>>>
>>>>
>>>>
>>>>
>>>>>>>>:1076)
>>>>>>>>|       at
>>>>>>>>
>>>>
>>>>com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java
>>>>
>>>>
>>>>
>>>>
>>>>>>>>:1061)
>>>>>>>>|       at
>>>>>>>>
>>>>
>>>>org.jboss.resource.adapter.jdbc.WrappedPreparedStatement.executeUpdat
>>>>
>>>>
>>>>
>>>>
>>>>>>>>e(Unknown Source)
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>|       at
>>>>>>>>>
>>>>
>>>>com.sony.framework.util.sqltemplate2.UpdateSQLCommand.runStatement(Up
>>>>
>>>>
>>>>
>>>>
>>>>>>>>>dateSQLCommand.java:65)
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>>From: Tetsuro IKEDA <tetsuro@xxxxxxxxxx>
>>>>>>>>>Reply-To: ml@xxxxxxxxxx
>>>>>>>>>To: ml@xxxxxxxxxx
>>>>>>>>>Subject: [mysql 12765] Re: Mysql JDBC接続時のサイズ制限
>>>>>>>>>Date: Thu, 16 Feb 2006 05:43:19 -0500
>>>>>>>>>
>>>>>>>>>こんにちは。池田です。
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>>Mysql JDBC接続時のサイズ制限(stateMentの長さ)がありますか。
>>>>>>>>>>もしあれば、どうやって調整(設定)しますでしょうか。
>>>>>>>>>
>>>>>>>>>java.sql.Statementを使う場合にサーバに送信できるクエリの最大長に 
>>>>>
>>>>>つい
>>>>
>>>>て
>>>>
>>>>
>>>>
>>>>
>>>>>>の
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>>>>ご質問でしょうか? 
>>>>>>>>>
>>>>>>>>>質問の意図をもう少し詳しく教えてください。
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>--
>>>>>>>>>Tetsuro Ikeda, Intern Development & Support
>>>>>>>>>MySQL Inc, www.mysql.com
>>>>>>>>>Office: +1-206-336-2030   Mobile: +1-206-661-4293
>>>>>>>>>Are you MySQL certified?  www.mysql.com/certification
>>>>>>>>>
>>>>>>>>
>>>>>>>>_________________________________________________________________
>>>>>>>>迷惑メールやウイルスへの対策も万全「MSN Hotmail」
>>>>>>>>http://promotion.msn.co.jp/hotmail/
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>--
>>>>>>>Tetsuro Ikeda, Intern Development & Support
>>>>>>>MySQL Inc, www.mysql.com
>>>>>>>Office: +1-206-336-2030   Mobile: +1-206-661-4293
>>>>>>>Are you MySQL certified?  www.mysql.com/certification
>>>>>>>
>>>>>>
>>>>>>_________________________________________________________________
>>>>>>パソコンでも携帯電話でも使える 「MSN Hotmail」
>>>>>>http://promotion.msn.co.jp/hotmail/
>>>>>>
>>>>>
>>>>>
>>>>>-- 
>>>>>Tetsuro Ikeda, Intern Development & Support
>>>>>MySQL Inc, www.mysql.com
>>>>>Office: +1-206-336-2030   Mobile: +1-206-661-4293
>>>>>Are you MySQL certified?  www.mysql.com/certification
>>>>>
>>>>
>>>>_________________________________________________________________
>>>>MSNショッピングでXbox360を早速チェック! 
>>>>http://shopping.msn.co.jp/softcontent/softcontent.aspx?scmId=593
>>>>
>>>
>>>
>>>
>>
> 
> 


-- 
Tetsuro Ikeda, Intern Development & Support
MySQL Inc, www.mysql.com
Office: +1-206-336-2030   Mobile: +1-206-661-4293
Are you MySQL certified?  www.mysql.com/certification

[前][次][番号順一覧][スレッド一覧]

     12763 2006-02-16 13:49 ["Matsunobu, Yoshinor] Re: MySQL のバックアップ・復元について  
     12764 2006-02-16 17:24 ┣["kyou tech" <kyou_te] Mysql JDBC接続時のサイズ制限         
     12765 2006-02-16 19:43 ┃┗[Tetsuro IKEDA <tetsu]                                     
     12766 2006-02-16 20:18 ┃ ┗["kyou tech" <kyou_te]                                   
     12767 2006-02-16 21:07 ┃  ┗[Tetsuro IKEDA <tetsu]                                 
     12768 2006-02-17 10:37 ┃   ┗["kyou tech" <kyou_te]                               
     12769 2006-02-17 12:04 ┃    ┗[Tetsuro IKEDA <tetsu]                             
     12770 2006-02-17 14:32 ┃     ┗["kyou tech" <kyou_te]                           
     12771 2006-02-17 15:02 ┃      ┗[Tetsuro IKEDA <tetsu]                         
     12772 2006-02-17 15:15 ┃       ┗[Tetsuro IKEDA <tetsu]                       
     12773 2006-02-17 16:42 ┃        ┗[Tetsuro IKEDA <tetsu]                     
->   12775 2006-02-18 16:10 ┃         ┗[Tetsuro IKEDA <tetsu]                   
     12776 2006-02-19 21:08 ┃          ┗["kyou tech" <kyou_te]                 
     12777 2006-02-20 04:06 ┃           ┗[Tetsuro IKEDA <tetsu]               
     12778 2006-02-20 06:43 ┃            ┗[Tetsuro IKEDA <tetsu]             
     12779 2006-02-20 14:51 ┃             ┗["kyou tech" <kyou_te]           
     12780 2006-02-20 15:01 ┃              ┗[Tetsuro IKEDA <tetsu]         
     12781 2006-02-20 15:37 ┃               ┗["kyou tech" <kyou_te]       
     12782 2006-02-20 15:45 ┃                ┗[Tetsuro IKEDA <tetsu]     
     12774 2006-02-17 17:59 ┗[baya <bayapbayap@xxx]