mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	BUILD/compile-pentium-debug: Use /usr/local/BerkeleyDB-dbug/ if available BUILD/compile-pentium: Use /usr/local/BerkeleyDB-opt/ if available Docs/internals.texi: Added 'unedited' documentation for mysys functions Docs/manual.texi: Cleanups client/mysql.cc: Added client language to status client/mysqltest.c: Fixed bug with --no-defaults heap/_check.c: Added option to print status. heap/hp_close.c: Update to use new status interface heap/hp_hash.c: Clean up hash function and add new experimental hash heap/hp_test1.c: Update to use new status interface heap/hp_test2.c: Update to use new status interface include/heap.h: Update to use new status interface mysql-test/r/key_diff.result: Cleanup tests that may give rows in random order mysql-test/r/type_blob.result: Removed \r from output as this confused bk mysql-test/t/key_diff.test: Cleanup tests that may give rows in random order BitKeeper/etc/ignore: Added Docs/my_sys.doc to the ignore list mysql-test/t/type_blob.test: Removed \r from output as this confused bk mysys/hash.c: Add new experimental hash function scripts/safe_mysqld.sh: Added --mysqld option sql/ha_innobase.cc: Fixed store_locking sql/mysqld.cc: Cleaned up warning messages
		
			
				
	
	
		
			448 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			448 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| \input texinfo  @c -*-texinfo-*-
 | |
| @c Copyright 1998 TcX AB, Detron HB and Monty Program KB
 | |
| @c
 | |
| @c %**start of header
 | |
| @setfilename internals.info
 | |
| @c We want the types in the same index
 | |
| @c @synindex tp fn cp
 | |
| @synindex cp fn
 | |
| @iftex
 | |
| @c Well this is normal in Europe. Maybe this should go into the include.texi?
 | |
| @afourpaper
 | |
| @end iftex
 | |
| @c Get version and other info
 | |
| @include include.texi
 | |
| @ifclear tex-debug
 | |
| @c This removes the black squares in the right margin
 | |
| @finalout
 | |
| @end ifclear
 | |
| @c Set background for HTML
 | |
| @set _body_tags BGCOLOR=#FFFFFF TEXT=#000000 LINK=#101090 VLINK=#7030B0
 | |
| @settitle @strong{MySQL} internals Manual for version @value{mysql_version}.
 | |
| @setchapternewpage off
 | |
| @paragraphindent 0
 | |
| @c %**end of header
 | |
| 
 | |
| @ifinfo
 | |
| @format
 | |
| START-INFO-DIR-ENTRY
 | |
| * mysql-internals: (mysql-internals).               @strong{MySQL} internals.
 | |
| END-INFO-DIR-ENTRY
 | |
| @end format
 | |
| @end ifinfo
 | |
| 
 | |
| @titlepage
 | |
| @sp 10
 | |
| @center @titlefont{@strong{MySQL} Internals Manual}
 | |
| @sp 10
 | |
| @center Copyright @copyright{} 1998 TcX AB, Detron HB and Monty Program KB
 | |
| @end titlepage
 | |
| 
 | |
| @node Top, Introduction, (dir), (dir)
 | |
| 
 | |
| @ifinfo
 | |
| This is a manual about @strong{MySQL} internals.
 | |
| @end ifinfo
 | |
| 
 | |
| @menu
 | |
| @end menu
 | |
| 
 | |
| @node caching
 | |
| @chapter How MySQL handles caching
 | |
| 
 | |
| @strong{MySQL} has the following caches:
 | |
| (Note that the some of the filename have a wrong spelling of cache. :)
 | |
| 
 | |
| @itemize @bullet
 | |
| 
 | |
| @item Key cache
 | |
| A shared cache for all B-tree index blocks in the different NISAM
 | |
| files. Uses hashing and reverse linked lists for quick caching of the
 | |
| last used blocks and quick flushing of changed entries for a specific
 | |
| table. (@file{mysys/mf_keycash.c})
 | |
| 
 | |
| @item Record cache
 | |
| This is used for quick scanning of all records in a table.
 | |
| (@file{mysys/mf_iocash.c} and @file{isam/_cash.c})
 | |
| 
 | |
| @item Table cache
 | |
| This holds the last used tables. (@file{sql/sql_base.cc})
 | |
| 
 | |
| @item Hostname cache
 | |
| For quick lookup (with reverse name resolving). Is a must when one has a
 | |
| slow DNS. 
 | |
| (@file{sql/hostname.cc})
 | |
| 
 | |
| @item Privilege cache
 | |
| To allow quick change between databases the last used privileges are
 | |
| cached for each user/database combination.
 | |
| (@file{sql/sql_acl.cc})
 | |
| 
 | |
| @item Heap table cache
 | |
| Many use of GROUP BY or DISTINCT caches all found
 | |
| rows in a HEAP table (this is a very quick in-memory table with hash index)
 | |
| 
 | |
| @item Join row cache.
 | |
| For every full join in a SELECT statement (a full join here means there
 | |
| were no keys that one could use to find the next table in a list), the
 | |
| found rows are cached in a join cache.  One SELECT query can use many
 | |
| join caches in the worst case.
 | |
| @end itemize
 | |
| 
 | |
| @node flush tables
 | |
| @chapter How MySQL handles flush tables
 | |
| 
 | |
| @itemize @bullet
 | |
| 
 | |
| @item
 | |
| Flush tables is handled in @code{sql/sql_base.cc::close_cached_tables()}.
 | |
| 
 | |
| @item
 | |
| The idea of flush tables is to force all tables to be closed. This
 | |
| is mainly to ensure that if someone adds a new table outside of
 | |
| @strong{MySQL} (for example with @code{cp}) all threads will start using 
 | |
| the new table. This will also ensure that all table changes are flushed 
 | |
| to disk (but of course not as optimally as simple calling a sync on
 | |
| all tables)!
 | |
| 
 | |
| @item
 | |
| When one does a @code{FLUSH TABLES}, the variable @code{refresh_version} 
 | |
| will be incremented. Every time a thread releases a table it checks if
 | |
| the refresh version of the table (updated at open) is the same as
 | |
| the current refresh_version.  If not it will close it and broadcast
 | |
| a signal on COND_refresh (to wait any thread that is waiting for
 | |
| all instanses of a table to be closed).
 | |
| 
 | |
| @item
 | |
| The current @code{refresh_version} is also compared to the open 
 | |
| @code{refresh_version} after a thread gets a lock on a table.  If the 
 | |
| refresh version is different the thread will free all locks, reopen the
 | |
| table and try to get the locks again;  This is just to quickly get all 
 | |
| tables to use the newest version.  This is handled by
 | |
| @code{sql/lock.cc::mysql_lock_tables()} and 
 | |
| @code{sql/sql_base.cc::wait_for_tables()}.
 | |
| 
 | |
| @item
 | |
| When all tables has been closed @code{FLUSH TABLES} will return an ok 
 | |
| to client.
 | |
| 
 | |
| @item
 | |
| If the thread that is doing @code{FLUSH TABLES} has a lock on some tables,
 | |
| it will first close the locked tables, then wait until all other threads
 | |
| have also closed them, and then reopen them and get the locks.
 | |
| After this it will give other threads a chance to open the same tables.
 | |
| 
 | |
| @end itemize
 | |
| 
 | |
| @node Filesort
 | |
| @chapter How MySQL does sorting (filesort)
 | |
| 
 | |
| @itemize @bullet
 | |
| 
 | |
| @item
 | |
| Read all rows according to key or by table scanning.
 | |
| 
 | |
| @item
 | |
| Store the sort-key in a buffer (@code{sort_buffer}).
 | |
| 
 | |
| @item
 | |
| When the buffer gets full, run a qsort on it and store the result
 | |
| in a temporary file.  Save a pointer to the sorted block.
 | |
| 
 | |
| @item
 | |
| Repeat the above until all rows have been read.
 | |
| 
 | |
| @item
 | |
| Repeat the following until there is less than @code{MERGEBUFF2} (15) 
 | |
| blocks left.
 | |
| 
 | |
| @item
 | |
| Do a multi-merge of up to @code{MERGEBUFF} (7) regions to one block in
 | |
| another temporary file.  Repeat until all blocks from the first file
 | |
| are in the second file.
 | |
| 
 | |
| @item
 | |
| On the last multi-merge, only the pointer to the row (last part of
 | |
| the sort-key) is written to a result file.
 | |
| 
 | |
| @item
 | |
| Now the code in @file{sql/records.cc} will be used to read through them
 | |
| in sorted order by using the row pointers in the result file.
 | |
| To optimize this, we read in a big block of row pointers, sort these
 | |
| and then we read the rows in the sorted order into a row buffer
 | |
| (@code{record_buffer}) .
 | |
| 
 | |
| @end itemize
 | |
| 
 | |
| @node Coding guidelines
 | |
| @chapter Coding guidelines
 | |
| 
 | |
| @itemize @bullet
 | |
| 
 | |
| @item
 | |
| We are using @uref{http://www.bitkeeper.com/, BitKeeper} for source management.
 | |
| 
 | |
| @item
 | |
| You should use the @strong{MySQL} 3.23 or 4.0 source for all developments.
 | |
| 
 | |
| @item
 | |
| If you have any questions about the @strong{MySQL} source, you can post these
 | |
| to @email{developers@@mysql.com} and we will answer them.
 | |
| Note that we will shortly change the name of this list to
 | |
| @email{internals@@mysql.com}, to more accurately reflect what should be
 | |
| posted to this list.
 | |
| 
 | |
| @item
 | |
| Try to write code in a lot of black boxes that can be reused or at
 | |
| least have a clean interface.
 | |
| 
 | |
| @item
 | |
| Reuse code;  There is already a lot of algorithms in MySQL for list handling,
 | |
| queues, dynamic and hashed arrays, sorting, etc. that can be reused.
 | |
| 
 | |
| @item
 | |
| Try to always write optimized code, so that you don't have to
 | |
| go back and rewrite it a couple of months later.  It's better to
 | |
| spend 3 times as much time designing and writing an optimal function than
 | |
| having to do it all over again later on.
 | |
| 
 | |
| @item
 | |
| Avoid CPU wasteful code, even where it does not matter, so that
 | |
| you will not develop sloppy coding habits.
 | |
| 
 | |
| @item
 | |
| If you can write it in fewer lines, do it (as long as the code will not
 | |
| be slower or much harder to read).
 | |
| 
 | |
| @item
 | |
| Do not check the same pointer for @code{NULL} more than once.
 | |
| 
 | |
| @item
 | |
| Use long function and variable names in English;  This makes your
 | |
| code easier to read.
 | |
| 
 | |
| @item
 | |
| Think assembly - make it easier for the compiler to optimize your code.
 | |
| 
 | |
| @item
 | |
| Comment your code when you do something that someone else may think
 | |
| is not ''trivial''.
 | |
| 
 | |
| @item
 | |
| Use the @code{my_*} functions like @code{my_read()}/@code{my_write()}/
 | |
| @code{my_malloc()} that you can find in the @code{mysys} library instead 
 | |
| of the direct system calls;  This will make your code easier to debug and 
 | |
| more portable.
 | |
| 
 | |
| @item
 | |
| Use @code{libstring} functions instead of standard libc string functions
 | |
| whenever possible.
 | |
| 
 | |
| @item
 | |
| Avoid using @code{malloc()} (its REAL slow);  For memory allocations 
 | |
| that only need to live for the lifetime of one thread, one should use
 | |
| @code{sql_alloc()} instead.
 | |
| 
 | |
| @item
 | |
| Before making big design decisions, please first post a summary of
 | |
| what you want to do, why you want to do it, and how you plan to do
 | |
| it.  This way we can easily provide you with feedback and also
 | |
| easily discuss it thoroughly if some other developer thinks there is better
 | |
| way to do the same thing!
 | |
| 
 | |
| @item
 | |
| Use my_var as opposed to myVar or MyVar (@samp{_} rather than dancing SHIFT
 | |
| to seperate words in identifiers).
 | |
| 
 | |
| @item
 | |
| Class names start with a capital letter.
 | |
| 
 | |
| @item
 | |
| Structure types are @code{typedef}'ed to an all-caps identifier.
 | |
| 
 | |
| @item
 | |
| Any @code{#define}'s are in all-caps.
 | |
| 
 | |
| @item
 | |
| Matching @samp{@{} are in the same column.
 | |
| 
 | |
| @item
 | |
| Functions return 0 on success, and non-zero on error, so you can do:
 | |
| 
 | |
| @example
 | |
| if(a() || b() || c()) { error("something went wrong"); }
 | |
| @end example
 | |
| 
 | |
| @item
 | |
| Using @code{goto} is okay if not abused.
 | |
| 
 | |
| @item
 | |
| Avoid default variable initalizations, use @code{LINT_INIT()} if the
 | |
| compiler complains after making sure that there is really no way
 | |
| the variable can be used uninitialized.
 | |
| 
 | |
| @item
 | |
| Do not instantiate a class if you do not have to.
 | |
| 
 | |
| @item
 | |
| Use pointers rather than array indexing when operating on strings.
 | |
| 
 | |
| @end itemize
 | |
| 
 | |
| @node mysys functions
 | |
| @chapter mysys functions
 | |
| 
 | |
| Functions i mysys: (For flags se my_sys.h)
 | |
| 
 | |
|  int my_copy _A((const char *from,const char *to,myf MyFlags));
 | |
| 	- Copy file
 | |
| 
 | |
|  int my_delete _A((const char *name,myf MyFlags));
 | |
| 	- Delete file
 | |
| 
 | |
|  int my_getwd _A((string buf,uint size,myf MyFlags));
 | |
|  int my_setwd _A((const char *dir,myf MyFlags));
 | |
| 	- Get and set working directory
 | |
| 
 | |
|  string my_tempnam _A((const char *pfx,myf MyFlags));
 | |
| 	- Make a uniq temp file name by using dir and adding something after
 | |
| 	 pfx to make name uniq. Name is made by adding a uniq 6 length-string
 | |
| 	 and TMP_EXT after pfx.
 | |
| 	 Returns pointer to malloced area for filename. Should be freed by
 | |
| 	 free().
 | |
| 
 | |
|  File my_open _A((const char *FileName,int Flags,myf MyFlags));
 | |
|  File my_create _A((const char *FileName,int CreateFlags,
 | |
| 			  int AccsesFlags, myf MyFlags));
 | |
|  int my_close _A((File Filedes,myf MyFlags));
 | |
|  uint my_read _A((File Filedes,byte *Buffer,uint Count,myf MyFlags));
 | |
|  uint my_write _A((File Filedes,const byte *Buffer,uint Count,
 | |
| 			 myf MyFlags));
 | |
|  ulong my_seek _A((File fd,ulong pos,int whence,myf MyFlags));
 | |
|  ulong my_tell _A((File fd,myf MyFlags));
 | |
| 	- Use instead of open,open-with-create-flag, close read and write
 | |
| 	  to get automatic error-messages (flag: MYF_WME) and only have
 | |
| 	  to test for != 0 if error (flag: MY_NABP).
 | |
| 
 | |
|  int my_rename _A((const char *from,const char *to,myf MyFlags));
 | |
| 	- Rename file
 | |
| 
 | |
|  FILE *my_fopen _A((const char *FileName,int Flags,myf MyFlags));
 | |
|  FILE *my_fdopen _A((File Filedes,int Flags,myf MyFlags));
 | |
|  int my_fclose _A((FILE *fd,myf MyFlags));
 | |
|  uint my_fread _A((FILE *stream,byte *Buffer,uint Count,myf MyFlags));
 | |
|  uint my_fwrite _A((FILE *stream,const byte *Buffer,uint Count,
 | |
| 			  myf MyFlags));
 | |
|  ulong my_fseek _A((FILE *stream,ulong pos,int whence,myf MyFlags));
 | |
|  ulong my_ftell _A((FILE *stream,myf MyFlags));
 | |
| 	- Same read-interface for streams as for files
 | |
| 
 | |
|  gptr _mymalloc _A((uint uSize,const char *sFile,
 | |
| 			  uint uLine, myf MyFlag));
 | |
|  gptr _myrealloc _A((string pPtr,uint uSize,const char *sFile,
 | |
| 			   uint uLine, myf MyFlag));
 | |
|  void _myfree _A((gptr pPtr,const char *sFile,uint uLine));
 | |
|  int _sanity _A((const char *sFile,unsigned int uLine));
 | |
|  gptr _myget_copy_of_memory _A((const byte *from,uint length,
 | |
| 				      const char *sFile, uint uLine,
 | |
| 				      myf MyFlag));
 | |
| 	- malloc(size,myflag) is mapped to this functions if not compiled
 | |
| 	  with -DSAFEMALLOC
 | |
| 
 | |
|  void TERMINATE _A((void));
 | |
| 	- Writes malloc-info on stdout if compiled with -DSAFEMALLOC.
 | |
| 
 | |
|  int my_chsize _A((File fd,ulong newlength,myf MyFlags));
 | |
| 	- Change size of file
 | |
| 
 | |
|  void my_error _D((int nr,myf MyFlags, ...));
 | |
| 	- Writes message using error number (se mysys/errors.h) on
 | |
| 	  stdout or curses if  MYSYS_PROGRAM_USES_CURSES() is called.
 | |
| 
 | |
|  void my_message _A((const char *str,myf MyFlags));
 | |
| 	- Writes message-string on
 | |
| 	 stdout or curses if  MYSYS_PROGRAM_USES_CURSES() is called.
 | |
| 
 | |
|  void my_init _A((void ));
 | |
| 	- Start each program (in main) with this.
 | |
|  void my_end _A((int infoflag));
 | |
| 	- Gives info about program.
 | |
| 	- If infoflag & MY_CHECK_ERROR prints if some files are left open
 | |
| 	- If infoflag & MY_GIVE_INFO   prints timing info and malloc info
 | |
| 	  about prog.
 | |
| 
 | |
|  int my_redel _A((const char *from, const char *to, int MyFlags));
 | |
| 	- Delete from before rename of to to from. Copyes state from old
 | |
| 	  file to new file. If MY_COPY_TIME is set sets old time.
 | |
| 
 | |
|  int my_copystat _A((const char *from, const char *to, int MyFlags));
 | |
| 	- Copye state from old file to new file.
 | |
| 	  If MY_COPY_TIME is set sets copy also time.
 | |
| 
 | |
|  string my_filename _A((File fd));
 | |
| 	- Give filename of open file.
 | |
| 
 | |
|  int dirname _A((string to,const char *name));
 | |
| 	- Copy name of directory from filename.
 | |
| 
 | |
|  int test_if_hard_path _A((const char *dir_name));
 | |
| 	- Test if dirname is a hard path (Starts from root)
 | |
| 
 | |
|  void convert_dirname _A((string name));
 | |
| 	- Convert dirname acording to system.
 | |
| 	  - In MSDOS changes all caracters to capitals and changes '/' to
 | |
| 	    '\'
 | |
|  string fn_ext _A((const char *name));
 | |
| 	- Returns pointer to extension in filename
 | |
|  string fn_format _A((string to,const char *name,const char *dsk,
 | |
| 			    const char *form,int flag));
 | |
| 	format a filename with replace of library and extension and
 | |
| 	converts between different systems.
 | |
| 	params to and name may be identicall
 | |
| 	function dosn't change name if name != to
 | |
| 	Flag may be:	1   force replace filnames library with 'dsk'
 | |
| 			2   force replace extension with 'form' */
 | |
| 			4   force Unpack filename (replace ~ with home)
 | |
| 			8   Pack filename as short as possibly for output to
 | |
| 			    user.
 | |
| 	All open requests should allways use at least:
 | |
| 	"open(fn_format(temp_buffe,name,"","",4),...)" to unpack home and
 | |
| 	convert filename to system-form.
 | |
| 
 | |
|  string fn_same _A((string toname,const char *name,int flag));
 | |
| 	- Copys directory and extension from name to toname if neaded.
 | |
| 	  copy can be forced by same flags that in fn_format.
 | |
| 
 | |
|  int wild_compare _A((const char *str,const char *wildstr));
 | |
| 	- Compare if str matches wildstr. Wildstr can contain "*" and "?"
 | |
| 	  as match-characters.
 | |
| 	  Returns 0 if match.
 | |
| 
 | |
|  void get_date _A((string to,int timeflag));
 | |
| 	- Get current date in a form ready for printing.
 | |
| 
 | |
|  void soundex _A((string out_pntr, string in_pntr))
 | |
| 	- Makes in_pntr to a 5 chars long string. All words that sounds
 | |
| 	  alike have the same string.
 | |
| 
 | |
|  int init_key_cache _A((ulong use_mem,ulong leave_this_much_mem));
 | |
| 	- Use cacheing of keys in MISAM, PISAM, and ISAM.
 | |
| 	  KEY_CACHE_SIZE is a good size.
 | |
| 	  - Remember to lock databases for optimal cacheing
 | |
| 
 | |
|  void end_key_cache _A((void));
 | |
| 	- End key-cacheing.
 | |
| 
 | |
| 
 | |
| @c The Index was empty, and ugly, so I removed it. (jcole, Sep 7, 2000)
 | |
| 
 | |
| @c @node Index
 | |
| @c @unnumbered Index
 | |
| 
 | |
| @c @printindex fn
 | |
| 
 | |
| @summarycontents
 | |
| @contents
 | |
| 
 | |
| @bye
 |