myisam.txt 30.7 KB
Newer Older
H
hustjieke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901
#.# mi_changed()

int mi_is_changed(MI_INFO *mip)

#.#.1 Description

Reports whether any changes have occurred to the MyISAM table associated with mip. 

For information only, I notice that mi_changed() is a wrapper around this: (_mi_readinfo(info,F_RDLCK,1)).

#.#.2 Return values

Zero if the table has not changed. Non-zero (-1) if the table has changed.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

if( mi_changed( mip )) printf( "file has changed" );
====================
#.# mi_close()

int mi_close( MI_INFO *mip )

#.#.1 Description

Closes the MyISAM table associated with mip, a structure created by mi_open().
Any locks on that file pointer are released.
The MI_INFO structure mip is released.
See also mi_panic() which can be used to close all open MyISAM files.
mip is a pointer to the MI_INFO returned by mi_open().

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

result = mi_close(mip);
====================
#.# mi_create()

int mi_create( const char *name, uint keys, MI_KEYDEF *keydefs,
          uint columns, MI_COLUMNDEF *recinfo, 
          uint uniques, MI_UNIQUEDEF *uniquedefs, 
          MI_CREATE_INFO *ci, uint flags ) 

#.#.1 Description

Creates a new MyISAM table.
Documentation for this function is not complete because I am not using mi_create directly.
Because all our tables are used with MySQL, I create new tables using SQL "CREATE TABLE" via the C API. 
See MySQL Appendix B "Choosing a table type".
MyISAM allows about 32 indexes. However the official MySQL limit is 16 until MySQL 4.0.

The parameters are specified as follows:
name		The file pathname, excluding the suffixes.
keys		Number of indexes.
keydefs	A MI_KEYDEF structure containing key definitions. 
HA_KEYTYPE_END=0 
HA_KEYTYPE_TEXT=1,                    /* Key is sorted as letters */    
HA_KEYTYPE_BINARY=2,                  /* Key is sorted as unsigned chars
HA_KEYTYPE_SHORT_INT=3,                                                 
HA_KEYTYPE_LONG_INT=4,                                                  
HA_KEYTYPE_FLOAT=5,                                                     
HA_KEYTYPE_DOUBLE=6,                                                    
HA_KEYTYPE_NUM=7,                     /* Not packed num with pre-space *
HA_KEYTYPE_USHORT_INT=8,                                                
HA_KEYTYPE_ULONG_INT=9,                                                 
HA_KEYTYPE_LONGLONG=10,                                                 
HA_KEYTYPE_ULONGLONG=11,                                                
HA_KEYTYPE_INT24=12,                                                    
HA_KEYTYPE_UINT24=13,                                                   
HA_KEYTYPE_INT8=14,                                                     
HA_KEYTYPE_VARTEXT=15,                /* Key is sorted as letters */    
HA_KEYTYPE_VARBINARY=16               /* Key is sorted as unsigned chars
columns	The number of columns.
recinfo		A MI_COLUMNDEF structure containing column definitions. 
uniques	The number of unique indexes.
uniquedefs	A MI_UNIQUEDEF structure containing unique index definitions. 
ci	A MI_CREATE_INFO structure containing column definitions.
flags	a pointer to the record buffer that will contain the row.

#.#.2 Return values

Zero if the create is successful. Non-zero if an error occurs.

#.#.3 Errors

HA_WRONG_CREATE_OPTION
 means that some of the arguments was wrong.
appart from the above one can get any unix error that one can get from open(), write() or close().

#.#.4 Examples

if (mi_create(fn_format(name,filename,"",MI_NAME_IEXT, 4+ (opt_follow_links ? 16 : 0)),
              share.base.keys - share.state.header.uniques, keyinfo, share.base.fields, recdef, 
              share.state.header.uniques, uniquedef, &create_info, HA_DONT_TOUCH_DATA))
====================
#.# mi_delete()

int mi_delete(MI_INFO *mip, const byte *buf)

#.#.1 Description

Removes a row from a MyISAM table.

mip is an MI_INFO pointer to the open handle.
buf is the buffer containing the row that is to be deleted.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

EACCES
File was opened read-only.
HA_ERR_KEY_NOT_FOUND
No database read
HA_ERR_RECORD_CHANGED
The buffer contents were different to the actual row contents.
HA_ERR_CRASHED
The indexing has crashed.

#.#.4 Examples

if (mi_delete(file,read_record))
====================
#.# mi_delete_all()

int mi_delete_all_rows(MI_INFO *mip)
#.#.1 Description

Removes ALL rows from a MyISAM table.
This only clears the status information. The files are not truncated.

mip is an MI_INFO pointer to the open handle.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

EACCES
File was opened read-only.

#.#.4 Examples

error = mi_delete_all( mip );
====================
#.# mi_extra()

int mi_extra(MI_INFO *info, enum ha_extra_function function)

#.#.1 Description

Controls some special MyISAM modes.

The function parameter can be:
	HA_EXTRA_NORMAL=0			Optimize for space (def) 
HA_EXTRA_QUICK=1			Optimize for speed 
HA_EXTRA_RESET=2			Reset database to after open 
HA_EXTRA_CACHE=3			Cash record in HA_rrnd() 
HA_EXTRA_NO_CACHE=4			End cacheing of records (def) 
HA_EXTRA_NO_READCHECK=5		No readcheck on update 
HA_EXTRA_READCHECK=6			Use readcheck (def) 
HA_EXTRA_KEYREAD=7			Read only key to database 
HA_EXTRA_NO_KEYREAD=8		Normal read of records (def) 
HA_EXTRA_NO_USER_CHANGE=9	No user is allowed to write 
HA_EXTRA_KEY_CACHE=10 
HA_EXTRA_NO_KEY_CACHE=11 
HA_EXTRA_WAIT_LOCK=12		Wait until file is avalably (def) 
HA_EXTRA_NO_WAIT_LOCK=13		If file is locked, return quickly 
HA_EXTRA_WRITE_CACHE=14		Use write cache in ha_write() 
HA_EXTRA_FLUSH_CACHE=15		flush write_record_cache 
HA_EXTRA_NO_KEYS=16			Remove all update of keys 
HA_EXTRA_KEYREAD_CHANGE_POS=17 Keyread, but change pos 
xxxxchk -r must be used 
HA_EXTRA_REMEMBER_POS=18		Remember pos for next/prev 
HA_EXTRA_RESTORE_POS=19
HA_EXTRA_REINIT_CACHE=20		init cache from current record 
HA_EXTRA_FORCE_REOPEN=21		Datafile have changed on disk 
HA_EXTRA_FLUSH				Flush tables to disk 
HA_EXTRA_NO_ROWS			Don't write rows 

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

====================
#.# mi_make_application_key()

void mi_make_application_key(register MI_INFO *mip, uint keynr, uchar *key, const byte *record)

#.#.1 Description

Construct a key string for the given index, from the provided record buffer.
Monty wrote this function to: "to create an external key for an application from your record. It should work for all keys except BLOB and true VARCHAR (not supported by MySQL yet), but I don't think you have either of these!" He just wrote it, so I expect it to included in releases from about 3.23.15. ??

The parameters are:
A MI_INFO pointer mip.
The index number keynr.
The buffer to contain the formatted key string key.
The record buffer record.

#.#.2 Return values

The byte length of the created key string.
 
#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

uint new_length=_mi_make_application_key(info,i,new_key,newrec);
====================
#.# mi_open()

MI_INFO *mi_open( const char *name, int mode, uint handle_locking )

#.#.1 Description

Opens a MyISAM file for processing.
mi_open() returns a MI_INFO structure pointer that you must use in subsequent operations on the MyISAM file. MI_INFO structures are defined in "myisam/myisamdef.h", which is included in your program via your include myisam.h - used by both MyISAM and MySQL.
The name parameter must contain a null-terminated string without an extension, which is the filename of the MyISAM file to be processed.
There is no automatic positioning nor key selection.
Caution! It is extremely important to close MyISAM files after processing has finished, especially on operating systems without file-locking system calls. Failure to close MyISAM files using mi_close() or mi_panic() leaves the files locked on systems without these system calls.

name			Is the name of the file.
mode			Is the access mode parameter. Use one of the following access mode parameters:
O_RDONLY	to open for input only.
O_RDWR	opens the file for output.
O_SHARE	opens the file for both input and output. When used, O_SHARE should be added to O_RDONLY and O_RDWR.
handle_locking	is the locking mode parameter. Select from the following:
HA_OPEN_ABORT_IF_LOCKED	(0) exit with error if database is locked
HA_OPEN_WAIT_IF_LOCKED	(1) wait if database is locked
HA_OPEN_IGNORE_IF_LOCKED	(2) continue, but count-vars in st_i_info may be wrong. count-vars are automatically fixed after next isam request.

#.#.2 Return values

A pointer to MI_INFO for successfully open file. NULL if unsuccessful, when my_errno will contain the error code.

#.#.3 Errors

HA_ERR_OLD_FILE
wrong options
HA_ERR_CRASHED
wrong header
HA_ERR_UNSUPPORTED
too many keys or keys too long
HA_ERR_END_OF_FILE
empty file?
MY_FILE_ERROR
?
EACCES
cannot open in write mode
ENOMEM
not enough memory
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

pfm = mi_open("/D1/adir/perform",O_SHARE | O_RDONLY, HA_OPEN_ABORT_IF_LOCKED); 
====================
#.# mi_panic()

int mi_panic( enum ha_panic_function flag )

#.#.1 Description

mi_panic() is used to close any MyISAM files before exiting, or to safeguard file updates when using a shell.
The flag parameter specifies the function and can be:
HA_PANIC_CLOSE	Close all databases (MyISAM files).
HA_PANIC_WRITE	Unlock and write status, flushing all buffers to disk.
HA_PANIC_READ	Lock and read key info per HA_PANIC_WRITE.

The CLOSE function also writes buffers before it closes and turns logging off by closing the log file..
See also my_end(), a debugging function.
One use is to do a WRITE, use a shell to run myisamchk, then do a READ.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

result = mi_panic(HA_PANIC_CLOSE);
====================
#.# mi_position()

my_off_t mi_position(MI_INFO *mip)

#.#.1 Description

Gets the byte position in the file of the last record read.

mip is an MI_INFO pointer to the open handle.

#.#.2 Return values

Byte position if successful. Zero if an error occurred. ??

#.#.3 Errors

HA_OFFSET_ERROR
if there wasn't any active row.

#.#.4 Examples

currentpos = mi_position( mip );
====================
#.# mi_rfirst()

int mi_rfirst(MI_INFO *mip , byte *buf, int inx)

#.#.1 Description

Reads the first row in the MyISAM file according to the specified index.
If one want's to read rows in physical sequences, then one should instead use mi_scan() or mi_rrnd().

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
Inx is the index (key) number, which must be the same as currently selected.

mi_rfirst() works by setting the current position mip->lastpos to HA_OFFSET_ERROR (undefined) then calling mi_rnext().

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_rfirst( mip, buffer, keynum); 
====================
#.# mi_rkey()

int mi_rkey(MI_INFO *mip, byte *buf, int inx, const byte *key, uint key_len, enum ha_rkey_function 	search_flag)

#.#.1 Description

Reads the next row after the last row read, using the current index. 
If one want's to read rows in physical sequences, then one should instead use mi_scan() or mi_rrnd().

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
Inx is the index (key) number, which must be the same as currently selected.

If (mip->lastpos) is HA_OFFSET_ERROR (undefined) then mi_rnext() gives the first row.
If you specify a different index number than the last read used, you will get an error.
If the last (current) row has been changed since we read it, mi_rnext() will reposition from the position where that row WAS, not where it is now. (This behaviour is similar to CISAM and better than used in Codebase.)

mi_extra(HA_EXTRA_KEYREAD) can be called first, to cause mi_rkey to read the key but not the record. Then call mi_extra(HA_EXTRA_NO_KEYREAD) to resume normal behaviour.
 
#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_rnext( mip, buffer, keynum );
====================
#.# mi_rlast()

int mi_rlast(MI_INFO *mip , byte *buf, int inx)

#.#.1 Description

Reads the last row in the MyISAM file according to the specified index.
If one want's to read rows in physical sequences, then one should instead use mi_scan() or mi_rrnd().
mip is an MI_INFO pointer to the open handle.
buf is a pointer to the record buffer that will contain the row.
Inx is the index (key) number, which must be the same as currently selected.

mi_rlast() works by setting the current position (mip->lastpos) to HA_OFFSET_ERROR (undefined) then calling mi_rprev().

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_rlast( mip, buffer, keynum); 
====================
#.# mi_rnext()

int mi_rnext(MI_INFO *mip , byte *buf, int inx )

#.#.1 Description

Reads the next row after the last row read, using the current index. 
If one want's to read rows in physical sequences, then one should instead use mi_scan() or mi_rrnd().

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
Inx is the index (key) number, which must be the same as currently selected.

If (mip->lastpos) is HA_OFFSET_ERROR (undefined) then mi_rnext() gives the first row.
If you specify a different index number than the last read used, you will get an error.
If the last (current) row has been changed since we read it, mi_rnext() will reposition from the position where that row WAS, not where it is now. (This behaviour is similar to CISAM and better than used in Codebase.)

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_rnext( mip, buffer, keynum );
====================
#.# mi_rrnd()

int mi_rrnd( MI_INFO *mip , byte *buf, my_off_t filepos )

#.#.1 Description

Reads a row based on physical position.

Position can be calculated from record number only when fixed record lengths are used: 
position = mip->s.pack.header_length + recnum * mip->s->base.reclength. 
If filepos= HA_OFFSET_ERROR then it reads the next row.
And if (mip->lastpos == HA_OFFSET_ERROR) it reads the first row.

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
filepos is the byte position in the file of the required record.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_RECORD_DELETED
A deleted record was read. 
HA_ERR_END_OF_FILE
End of file.

#.#.4 Examples

error = mi_rrnd( mip, buffer, mip->nextpos );
====================
#.# mi_rprev()

int mi_rprev(MI_INFO *mip , byte *buf, int inx)

#.#.1 Description

Reads the row previous to the last row read, using the current index. 
If one wants to read rows in physical sequences, then one should instead use mi_scan() or mi_rrnd().

If (mip->lastpos) is HA_OFFSET_ERROR (undefined) then mi_rnext() gives the last row in the index.
If you specify a different index number than the last read used, you will get an error.
If the last (current) row has been changed since we read it, mi_rprev() will reposition from the position where that row WAS, not where it is now. This behaviour is similar to CISAM and better than used in Codebase. 

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
Inx is the index (key) number, which must be the same as currently selected.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_rprev( mip, buffer, keynum );
====================
#.# mi_rsame()

int mi_rsame(MI_INFO *mip, byte *buf, int inx)

#.#.1 Description

Reads the current row to get its latest contents. This is useful to refresh the record buffer in case someone else has changed it.
If inx is negative it reads by position. If inx is >= 0 it reads by key.
With mi_rsame() one can switch to use any other index for the current row. This is good if you have a user application that lets the user do 'read-next' on a row.  In this case, if the user want's to start scanning on another index, one simply has to do a mi_rsame() on the new index to activate this.

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.
inx is the index (key) number, or a negative number to select read by position not index. Maybe the negative number has to be (-1) to achieve this behaviour.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_WRONG_INDEX
an incorrect index number was supplied
HA_ERR_KEY_NOT_FOUND
info->lastpos was not defined, or the record was already deleted.

#.#.4 Examples

error = mi_rsame( m5mip, rec_ptr, keynum );
====================
#.# mi_scan()

int mi_scan(MI_INFO *mip, byte *buf)

#.#.1 Description

Reads the next row by physical position.

Deleted rows are bypassed.
mi_scan() uses a function pointer "read_rnd" that uses either lower level static or dynamic read functions, positioning from mip->nextpos. Read_rnd is defined in mi_open() depending if the table is Static (read*static - see mi_statrec.c), Compressed (read*pack - see mi_packrec.c), or Space packed or Blobs (read*dynamic - see mi_dynrec.c).
See also mi_scan_init() which initialises ready to mi_scan() through the whole table.

mip is an MI_INFO pointer to the open handle.
buf is the record buffer that will contain the row.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_END_OF_FILE
End of file
Otherwise one has probably got a fatal error like HA_ERR_CRASHED or some I-O related error from the Operating System.

#.#.4 Examples

error = mi_scan( mip, recbuff ); 
====================
#.# mi_scan_init()

int mi_scan_init(MI_INFO *mip[SB1])

#.#.1 Description

Initialises ready to mi_scan() through all rows.

mip is an MI_INFO pointer to the open handle.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

====================
#.# mi_status()

int mi_status(MI_INFO *mip, MI_ISAMINFO *x, uint flag)

#.#.1 Description

Gets information about the table.
It is used to get/fill the MI_ISAMINFO struct with statistics data about the MySQL server.  One can get information of the number of active rows, delete rows, file lengths...

mip is an MI_INFO pointer to the open handle.
flag is one of the following:
HA_STATUS_POS		Return position
HA_STATUS_NO_LOCK	Don't use external lock
HA_STATUS_TIME		Return update time
HA_STATUS_CONST		Return constants value
HA_STATUS_VARIABLE
HA_STATUS_ERRKEY
HA_STATUS_AUTO

#.#.2 Return values

Zero.
 
#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

====================
#.# mi_update()

int mi_update( MI_INFO *mip, const byte *oldbuf, byte *newbuf)

#.#.1 Description

Updates the contents of the current record.
By default you must supply an oldbuf record buffer with the current record contents. This is compared with the file as a guard in case someone else has changed the record in the meantime. *

mip is an MI_INFO pointer to the open handle.
oldbuf is the record buffer that contains the current record contents.
newbuf is the record buffer that contains the new record contents.

*Sometimes you might want to force an update without checking whether another user has changed the record since you last read it. This is somewhat dangerous, so it should ideally not be used. That can be accomplished by wrapping the mi_update() call in two calls to mi_extra(), using these functions:
HA_EXTRA_NO_READCHECK=5		No readcheck on update 
HA_EXTRA_READCHECK=6			Use readcheck (def)

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

EACCES
The file was opened for read-only access.
HA_ERR_RECORD_CHANGED
	When mi_update() read the current record contents before updating, it differed from oldbuf.
HA_ERR_CRASHED
Key could not be found ??
HA_ERR_FOUND_DUPP_KEY
HA_ERR_RECORD_FILE_FULL

#.#.4 Examples

error = mi_update( mip, oldbuf, newbuf );
====================
#.# mi_write()

int mi_write( MI_INFO *mip, byte *record)

#.#.1 Description

Writes a row to a MyISAM table.

mip is an MI_INFO pointer to the open handle.
The record contents are supplied in buf record buffer.

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

HA_ERR_FOUND_DUPP_KEY
A record already existed with a unique key same as this new record.
HA_ERR_RECORD_FILE_FULL
The error is given if you hit a system limit or if you try to create more rows in a table that you reserverd room for with mi_create().
ENOSPC
The disk is full.
EACCES
The file was opened for read-only access.

#.#.4 Examples

error = mi_write( m5mip, recbuf );
====================
#.# my_end()

void my_end(int infoflag) 

#.#.1 Description

Shows debugging information about open MyISAM handles.
my_end() exists primarily for MyISAM debugging.
It would not normally be used in a production environment. 
It can give a nice summary of how you have used my_xxx() functions.
It can be used to check that you have closed all files that you have opened.

infoflag	is the list function and can be:
MY_CHECK_ERROR		List which MyISAM handles are open.
MY_GIVE_INFO		Show runtime information.

#.#.2 Return values

Void

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

my_end(MY_CHECK_ERROR | MY_GIVE_INFO);
====================
#.# my_init()

void my_init( void )

#.#.1 Description

Performs MyISAM initialisation for program startup, particularly if using threads.

If using threads, be sure to call my_init() at start of program. (CFS does this in XPOPEN.) It is also safe to call my_init() when not using threads.

#.#.2 Return values

void
Sometimes my_errno might be meaningful if a warning is generated during debugging.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

my_init();
====================
#.# init_key_cache()

int init_key_cache( long int use_mem, (uint) reserve_mem;

#.#.1 Description

Starts and controls caching of keys. Call init_key_cache() to reserve memory for key caching and to start the caching. (CFS does this in XPOPEN if MYCACHE is defined (regular size), or MYCACHELARGE or MYCACHESMALL.)

Provide use_mem the number of bytes of memory to use for key caching by this process.
reserve_mem should be 0. This is just for very old systems with very little memory.

#.#.2 Return values

The number of 1kb memory blocks now allocated to key caching. Zero if key caching cannot be started (check my_errno), or key caching was already active.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

Blocks = init_key_cache( 65536L, IO_SIZE*4*10 );
====================
#.# _mi_make_key()

uint _mi_make_key( MI_INFO *mip, uint keynr, uchar *key, const char *record, my_off_t filepos)

#.#.1 Description

Construct a key string for the given index, from the provided record buffer.
??? When packed records are used ...
This is an internal function, not for use by applications. Monty says: "This can't be used to create an external key for an application from your record."
See mi_make_application_key() for a similar function that is useable by applications.

The parameters are:
A MI_INFO pointer mip.
The index number keynr.
The buffer to contain the formatted key string key.
The record buffer record.
???  A file position filepos or zero.

#.#.2 Return values

The byte length of the created key string.
 
#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

uint new_length=_mi_make_key(info,i,new_key,newrec,pos);
====================
#.# _mi_print_key()

void _mi_print_key(FILE *stream, MI_KEYSEG *keyseg, const uchar *key, uint length) 

#.#.1 Description

Prints a key in a user understandable format.
This is an internal function for debugging, not for use by applications.
??? Not yet fully documented. I just include it here so that I know it exists.

#.#.2 Return values

A readable print of the key contents goes to the specified output.
 
#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples

_mi_print_key(stdout,share->keyinfo[info->errkey].seg,info->lastkey, USE_WHOLE_KEY); 
====================
APPENDIX B		Choosing a table type        
(excerpt from manual.txt in MySQL 3.23.8-alpha)

With MySQL you can currently (version 3.23.5) choose between four usable table formats from a speed point of view.

Static (Fixed-length) table characteristics
* This is the default format. It's used when the table contains no `VARCHAR', `BLOB' or `TEXT' columns. 
* All `CHAR', `NUMERIC' and `DECIMAL' columns are space-padded to the column width. 
* Very quick. 
* Easy to cache. 
* Easy to reconstruct after a crash, because records are located in fixed positions. 
* Doesn't have to be reorganized (with `myisamchk') unless a huge number of records are deleted and you want to return free disk space to the operating system. 
* Usually requires more disk space than dynamic tables. 
                                                                      
Dynamic table characteristics 
* This format is used if the table contains any `VARCHAR', `BLOB' or `TEXT' columns. 
* All string columns are dynamic (except those with a length less than 4). 
* Each record is preceded by a bitmap indicating which columns are empty (`''') for string columns, or zero for numeric columns (this isn't the same as columns containing `NULL' values).  If a string column has a length of zero after removal of trailing spaces, or a numeric column has a value of zero, it is marked in the bit map and not saved to disk.  Non-empty strings are saved as a length byte plus the string contents. 
* Usually takes much less disk space than fixed-length tables. 
* Each record uses only as much space as is required. If a record becomes larger, it is split into as many pieces as required.  This results in record fragmentation. 
* If you update a row with information that extends the row length, the row will be fragmented.  In this case, you may have to run `myisamchk -r' from time to time to get better performance.  Use `myisamchk -ei tbl_name' for some statistics. 
* Not as easy to reconstruct after a crash, because a record may be fragmented into many pieces and a link (fragment) may be missing. 
* The expected row length for dynamic sized records is: 
3
+ (number of columns + 7) / 8
+ (number of char columns) 
+ packed size of numeric columns 
+ length of strings 
+ (number of NULL columns + 7) / 8 
There is a penalty of 6 bytes for each link. A dynamic record is linked whenever an update causes an enlargement of the record. 
Each new link will be at least 20 bytes, so the next enlargement will probably go in the same link.  If not, there will be another link. You may check how many links there are with `myisamchk -ed'. All links may be removed with `myisamchk -r'.

Compressed table characteristics 
* A read-only table made with the `myisampack' utility. All customers with extended *MySQL* email support are entitled to a copy of `myisampack' for their internal usage. 
* The uncompress code exists in all *MySQL* distributions so that even customers who don't have `myisampack' can read tables that were compressed with `myisampack' 
* Takes very little disk space. Minimises disk usage. 
* Each record is compressed separately (very little access overhead).  The header for a record is fixed (1-3 bytes) depending on the biggest record in the table.  Each column is compressed differently. Some of the compression types are: 
- There is usually a different Huffman table for each column.
- Suffix space compression. 
- Prefix space compression. 
- Numbers with value `0' are stored using 1 bit. 
- If values in an integer column have a small range, the column is stored using the smallest possible type. For example, a `BIGINT' column (8 bytes) may be stored as a `TINYINT' column (1 byte) if all values are in the range `0' to `255'.
- If a column has only a small set of possible values, the column type is converted to `ENUM'.
- A column may use a combination of the above compressions. 
* Can handle fixed or dynamic length records, but not `BLOB' or `TEXT' columns. 
* Can be uncompressed with `myisamchk'.

*MySQL* can support different index types, but the normal type is ISAM. 
This is a B-tree index and you can roughly calculate the size for the index file as `(key_length+4)*0.67', summed over all keys.  (This is for the worst case when all keys are inserted in sorted order.)

String indexes are space compressed. If the first index part is a string, it will also be prefix compressed.
Space compression makes the index file smaller if the string column has a lot of trailing space or is a `VARCHAR' column that is not always used to the full length. 
Prefix compression helps if there are many strings with an identical prefix.

In memory table characteristics 
HEAP tables only exists in memory so they are lost if `mysqld' is taken down or crashes. But since they are *very* fast they are usefull as anyway. 

The *MySQL* internal HEAP tables uses 100% dynamic hashing without overflow areas and don't have problems with delete. 

You can only access things by equality using a index (usually by the `=' operator) whith a heap table. 
The downside with HEAPS are: 
  1. You need enough extra memory for all HEAP tables that you want to use at the same time. 
  2. You can't search on a part of a index. 
  3. You can't search for the next entry in order (that is to use the index to do a `ORDER BY'). 
1. *MySQL* also cannot find out how approximately many rows there are between two values. This is used by the optimizer to chose which index to use. But on the other hand no disk seeks are even needed.
====================
#.# mi_()

#.#.1 Description

#.#.2 Return values

Zero if successful. Non-zero if an error occurred.

#.#.3 Errors

Nothing specific yet identified.

#.#.4 Examples
[SB1]int _mi_read_rnd_static_record(MI_INFO *info, byte *buf, my_off_t filepos, 
                               my_bool skipp_deleted_blocks)
int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)

Printed on 17/03/00

C-7