Merge work:/my/mysql into donna.mysql.com:/home/my/bk/mysql
BitKeeper/etc/ignore: added sql/share/*.sys Docs/manual.texi: Auto merged BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted
This commit is contained in:
commit
72b3120dcc
@ -187,3 +187,4 @@ sql-bench/Results-linux/ATIS-mysql_bdb-Linux_2.2.14_my_SMP_i686
|
|||||||
Docs/my_sys.doc
|
Docs/my_sys.doc
|
||||||
tmp/*
|
tmp/*
|
||||||
extra/resolve_stack_dump
|
extra/resolve_stack_dump
|
||||||
|
sql/share/*.sys
|
||||||
|
@ -1 +1,2 @@
|
|||||||
jani@hynda.mysql.fi
|
jani@hynda.mysql.fi
|
||||||
|
monty@donna.mysql.com
|
||||||
|
275
Docs/manual.texi
275
Docs/manual.texi
@ -288,6 +288,11 @@ BSD/OS Notes
|
|||||||
* BSDI3:: BSD/OS 3.x notes
|
* BSDI3:: BSD/OS 3.x notes
|
||||||
* BSDI4:: BSD/OS 4.x notes
|
* BSDI4:: BSD/OS 4.x notes
|
||||||
|
|
||||||
|
Mac OS X Notes
|
||||||
|
|
||||||
|
* Mac OS X Public Data::
|
||||||
|
* Mac OS X Server::
|
||||||
|
|
||||||
Windows Notes
|
Windows Notes
|
||||||
|
|
||||||
* Windows installation:: Installing @strong{MySQL} on Windows
|
* Windows installation:: Installing @strong{MySQL} on Windows
|
||||||
@ -610,6 +615,7 @@ MySQL Utilites
|
|||||||
* mysql:: The command line tool
|
* mysql:: The command line tool
|
||||||
* mysqladmin:: Administering a @strong{MySQL} server
|
* mysqladmin:: Administering a @strong{MySQL} server
|
||||||
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
|
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
|
||||||
|
* mysqlhotcopy:: Copying @code{MySQL} Databases and Tables
|
||||||
* mysqlimport:: Importing data from text files
|
* mysqlimport:: Importing data from text files
|
||||||
* perror:: Displaying error messages
|
* perror:: Displaying error messages
|
||||||
* mysqlshow:: Showing databases, tables and columns
|
* mysqlshow:: Showing databases, tables and columns
|
||||||
@ -846,7 +852,7 @@ Changes in release 4.0.x (Development; Alpha)
|
|||||||
|
|
||||||
Changes in release 3.23.x (Recommended; Gamma)
|
Changes in release 3.23.x (Recommended; Gamma)
|
||||||
|
|
||||||
* News-3.23.31::
|
* News-3.23.31:: Changes in release 3.23.31
|
||||||
* News-3.23.30:: Changes in release 3.23.30
|
* News-3.23.30:: Changes in release 3.23.30
|
||||||
* News-3.23.29:: Changes in release 3.23.29
|
* News-3.23.29:: Changes in release 3.23.29
|
||||||
* News-3.23.28:: Changes in release 3.23.28
|
* News-3.23.28:: Changes in release 3.23.28
|
||||||
@ -2260,6 +2266,11 @@ FutureForum Web Discussion Software.
|
|||||||
SupportWizard; Interactive helpdesk on the Web (This product includes a
|
SupportWizard; Interactive helpdesk on the Web (This product includes a
|
||||||
licensed copy of @strong{MySQL}.)
|
licensed copy of @strong{MySQL}.)
|
||||||
|
|
||||||
|
@item @uref{http://www.sonork.com/}@*
|
||||||
|
Sonork, Instant Messenger that is not only Internet oriented. It's
|
||||||
|
focused on private networks and on small to medium companies. Client
|
||||||
|
is free, server is free for up to 5 seats.
|
||||||
|
|
||||||
@item @uref{http://www.stweb.org/}@*
|
@item @uref{http://www.stweb.org/}@*
|
||||||
StWeb - Stratos Web and Application server - An easy-to-use, cross
|
StWeb - Stratos Web and Application server - An easy-to-use, cross
|
||||||
platform, Internet/Intranet development and deployment system for
|
platform, Internet/Intranet development and deployment system for
|
||||||
@ -7965,12 +7976,30 @@ by HP's compilers. I did not change the flags.
|
|||||||
@node Mac OS X, BEOS, HP-UX 11.x, Source install system issues
|
@node Mac OS X, BEOS, HP-UX 11.x, Source install system issues
|
||||||
@subsection Mac OS X Notes
|
@subsection Mac OS X Notes
|
||||||
|
|
||||||
You can get @strong{MySQL} to work on Mac OS X by following the links to
|
@menu
|
||||||
the Mac OS X ports. @xref{Useful Links}.
|
* Mac OS X Public Data::
|
||||||
|
* Mac OS X Server::
|
||||||
|
@end menu
|
||||||
|
|
||||||
@strong{MySQL} Version 3.23.7 should include all patches necessary to configure
|
@node Mac OS X Public Data, Mac OS X Server, Mac OS X, Mac OS X
|
||||||
it on Mac OS X. You must, however, first install the pthread package from
|
@subsubsection Mac OS X Public beta
|
||||||
@uref{http://www.prnet.de/RegEx/mysql.html} before configuring @strong{MySQL}.
|
|
||||||
|
@strong{MySQL} should work without any probelms on Mac OS X public beta.
|
||||||
|
(Darwin); You don't need the pthread patches for this os!
|
||||||
|
|
||||||
|
@node Mac OS X Server, , Mac OS X Public Data, Mac OS X
|
||||||
|
@subsubsection Mac OS X Server
|
||||||
|
|
||||||
|
Before trying to configure @strong{MySQL} on Mac OS X server you must
|
||||||
|
first first install the pthread package from
|
||||||
|
@uref{http://www.prnet.de/RegEx/mysql.html}. Note that this is not neeaded
|
||||||
|
|
||||||
|
Our binary for Mac OS X is compiled on Rhapsody 5.5 with the following
|
||||||
|
configure line:
|
||||||
|
|
||||||
|
@example
|
||||||
|
CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex --disable-shared
|
||||||
|
@end example
|
||||||
|
|
||||||
You might want to also add aliases to your shell's resource file to
|
You might want to also add aliases to your shell's resource file to
|
||||||
access @code{mysql} and @code{mysqladmin} from the command line:
|
access @code{mysql} and @code{mysqladmin} from the command line:
|
||||||
@ -8196,8 +8225,8 @@ which protocol is used:
|
|||||||
@end multitable
|
@end multitable
|
||||||
|
|
||||||
You can force a @strong{MySQL} client to use named pipes by specifying the
|
You can force a @strong{MySQL} client to use named pipes by specifying the
|
||||||
@code{--pipe} option. Use the @code{--socket} option to specify the name of
|
@code{--pipe} option or by specifying @code{.} as the host name.
|
||||||
the pipe.
|
Use the @code{--socket} option to specify the name of the pipe.
|
||||||
|
|
||||||
You can test whether or not @strong{MySQL} is working by executing the
|
You can test whether or not @strong{MySQL} is working by executing the
|
||||||
following commands:
|
following commands:
|
||||||
@ -9344,7 +9373,9 @@ Don't flush key buffers between writes for any @code{MyISAM} table.
|
|||||||
Enable system locking.
|
Enable system locking.
|
||||||
|
|
||||||
@item -T, --exit-info
|
@item -T, --exit-info
|
||||||
Print some debug info at exit.
|
This is a bit mask of different flags one can use for debugging the
|
||||||
|
mysqld server; One should not use this option if one doesn't know
|
||||||
|
exactly what it does!
|
||||||
|
|
||||||
@item --flush
|
@item --flush
|
||||||
Flush all changes to disk after each SQL command. Normally @strong{MySQL}
|
Flush all changes to disk after each SQL command. Normally @strong{MySQL}
|
||||||
@ -18443,7 +18474,7 @@ BACKUP TABLE tbl_name[,tbl_name...] TO '/path/to/backup/directory'
|
|||||||
Make a copy of all the table files to the backup directory that are the
|
Make a copy of all the table files to the backup directory that are the
|
||||||
minimum needed to restore it. Currenlty only works for @code{MyISAM}
|
minimum needed to restore it. Currenlty only works for @code{MyISAM}
|
||||||
tables. For @code{MyISAM} table, copies @code{.frm} (definition) and
|
tables. For @code{MyISAM} table, copies @code{.frm} (definition) and
|
||||||
@code{.MYD} (data) files. The index file can be rebuilt from those two.
|
@code{.MYD} (data) files. The index file can be rebuilt from those two.
|
||||||
|
|
||||||
During the backup, read lock will be held for each table, one at time,
|
During the backup, read lock will be held for each table, one at time,
|
||||||
as they are being backed up. If you want to backup several tables as
|
as they are being backed up. If you want to backup several tables as
|
||||||
@ -20167,8 +20198,8 @@ The status variables listed above have the following meaning:
|
|||||||
|
|
||||||
@multitable @columnfractions .35 .65
|
@multitable @columnfractions .35 .65
|
||||||
@item @strong{Variable} @tab @strong{Meaning}
|
@item @strong{Variable} @tab @strong{Meaning}
|
||||||
@item @code{Aborted_clients} @tab Number of connections aborted because the client died without closing the connection properly.
|
@item @code{Aborted_clients} @tab Number of connections aborted because the client died without closing the connection properly. @xref{Communication errors}.
|
||||||
@item @code{Aborted_connects} @tab Number of tries to connect to the @strong{MySQL} server that failed.
|
@item @code{Aborted_connects} @tab Number of tries to connect to the @strong{MySQL} server that failed. @xref{Communication errors}.
|
||||||
@item @code{Bytes_received} @tab Number of bytes received from all clients.
|
@item @code{Bytes_received} @tab Number of bytes received from all clients.
|
||||||
@item @code{Bytes_sent} @tab Number of bytes sent to all clients.
|
@item @code{Bytes_sent} @tab Number of bytes sent to all clients.
|
||||||
@item @code{Connections} @tab Number of connection attempts to the @strong{MySQL} server.
|
@item @code{Connections} @tab Number of connection attempts to the @strong{MySQL} server.
|
||||||
@ -20244,12 +20275,6 @@ If @code{Handler_read_rnd} is big, then you probably have a lot of
|
|||||||
queries that require @strong{MySQL} to scan whole tables or you have
|
queries that require @strong{MySQL} to scan whole tables or you have
|
||||||
joins that don't use keys properly.
|
joins that don't use keys properly.
|
||||||
@item
|
@item
|
||||||
If @code{Created_tmp_tables} or @code{Sort_merge_passes} are high then
|
|
||||||
your @code{mysqld} @code{sort_buffer} variables is probably too small.
|
|
||||||
@item
|
|
||||||
@code{Created_tmp_files} doesn't count the files needed to handle temporary
|
|
||||||
tables.
|
|
||||||
@item
|
|
||||||
If @code{Threads_created} is big, you may want to increase the
|
If @code{Threads_created} is big, you may want to increase the
|
||||||
@code{thread_cache_size} variable.
|
@code{thread_cache_size} variable.
|
||||||
@end itemize
|
@end itemize
|
||||||
@ -20274,6 +20299,7 @@ differ somewhat:
|
|||||||
| back_log | 50 |
|
| back_log | 50 |
|
||||||
| basedir | /my/monty/ |
|
| basedir | /my/monty/ |
|
||||||
| bdb_cache_size | 16777216 |
|
| bdb_cache_size | 16777216 |
|
||||||
|
| bdb_log_buffer_size | 32768 |
|
||||||
| bdb_home | /my/monty/data/ |
|
| bdb_home | /my/monty/data/ |
|
||||||
| bdb_max_lock | 10000 |
|
| bdb_max_lock | 10000 |
|
||||||
| bdb_logdir | |
|
| bdb_logdir | |
|
||||||
@ -20381,6 +20407,12 @@ The value of the @code{--basedir} option.
|
|||||||
|
|
||||||
@item @code{bdb_cache_size}
|
@item @code{bdb_cache_size}
|
||||||
The buffer that is allocated to cache index and rows for @code{BDB}
|
The buffer that is allocated to cache index and rows for @code{BDB}
|
||||||
|
tables. If you don't use @code{BDB} tables, you should start
|
||||||
|
@code{mysqld} with @code{--skip-bdb} to not waste memory for this
|
||||||
|
cache.
|
||||||
|
|
||||||
|
@item @code{bdb_log_buffer_size}
|
||||||
|
The buffer that is allocated to cache index and rows for @code{BDB}
|
||||||
tables. If you don't use @code{BDB} tables, you should set this to 0 or
|
tables. If you don't use @code{BDB} tables, you should set this to 0 or
|
||||||
start @code{mysqld} with @code{--skip-bdb} to not waste memory for this
|
start @code{mysqld} with @code{--skip-bdb} to not waste memory for this
|
||||||
cache.
|
cache.
|
||||||
@ -20552,7 +20584,13 @@ will be incremented. If you are using @code{--log-slow-queries}, the query
|
|||||||
will be logged to the slow query logfile. @xref{Slow query log}.
|
will be logged to the slow query logfile. @xref{Slow query log}.
|
||||||
|
|
||||||
@item @code{lower_case_table_names}
|
@item @code{lower_case_table_names}
|
||||||
Table names are stored in lowercase on disk.
|
Is 1 if table names are stored in lowercase on disk. On @strong{MySQL} on Unix
|
||||||
|
tables are always case-sensitive; Is this a big problem for you can
|
||||||
|
start @code{mysqld} with @code{-O lower_case_table_names=1}
|
||||||
|
|
||||||
|
In this case @strong{MySQL} will convert all table names to lower case on
|
||||||
|
storage and lookup. Not that you need to first convert your old table
|
||||||
|
names to lower case before starting @code{mysqld} with this option.
|
||||||
|
|
||||||
@item @code{max_allowed_packet}
|
@item @code{max_allowed_packet}
|
||||||
The maximum size of one packet. The message buffer is initialized to
|
The maximum size of one packet. The message buffer is initialized to
|
||||||
@ -21289,7 +21327,7 @@ When you use @code{LOCK TABLES}, you must lock all tables that you are
|
|||||||
going to use and you must use the same alias that you are going to use
|
going to use and you must use the same alias that you are going to use
|
||||||
in your queries! If you are using a table multiple times in a query
|
in your queries! If you are using a table multiple times in a query
|
||||||
(with aliases), you must get a lock for each alias! This policy ensures
|
(with aliases), you must get a lock for each alias! This policy ensures
|
||||||
that table locking is deadlock free andh makes the locking code smaller,
|
that table locking is deadlock free and makes the locking code smaller,
|
||||||
simpler and much faster.
|
simpler and much faster.
|
||||||
|
|
||||||
Note that you should @strong{NOT} lock any tables that you are using with
|
Note that you should @strong{NOT} lock any tables that you are using with
|
||||||
@ -22678,10 +22716,10 @@ Berkeley DB (@uref{http://www.sleepycat.com}) has provided
|
|||||||
crashes and also provides @code{COMMIT} and @code{ROLLBACK} on
|
crashes and also provides @code{COMMIT} and @code{ROLLBACK} on
|
||||||
transactions. In order to build MySQL Version 3.23.x (BDB support first
|
transactions. In order to build MySQL Version 3.23.x (BDB support first
|
||||||
appeared in Version 3.23.15) with support for @code{BDB} tables, you
|
appeared in Version 3.23.15) with support for @code{BDB} tables, you
|
||||||
will need Berkeley DB Version 3.2.3d or newer which can be downloaded from
|
will need Berkeley DB Version 3.2.3g or newer which can be downloaded from
|
||||||
@uref{http://www.mysql.com/downloads/mysql-3.23.html}. This is a patched
|
@uref{http://www.mysql.com/downloads/mysql-3.23.html}. This is a patched
|
||||||
version of Berkeley DB that is only available from @strong{MySQL}; the
|
version of Berkeley DB that is only available from @strong{MySQL}; the
|
||||||
standard Berkeley DB @strong{will not work with MySQL}.
|
standard Berkeley DB @strong{will not yet work with MySQL}.
|
||||||
|
|
||||||
@node BDB install, BDB start, BDB overview, BDB
|
@node BDB install, BDB start, BDB overview, BDB
|
||||||
@subsection Installing BDB
|
@subsection Installing BDB
|
||||||
@ -22851,6 +22889,11 @@ TABLE}.
|
|||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
It's very slow to open many BDB tables at the same time. If you are
|
||||||
|
going to use BDB tables, you should not have a very big table cache (>
|
||||||
|
256 ?) and you should use @code{--no-auto-rehash} with the @code{mysql}
|
||||||
|
client. We plan to partly fix this in 4.0.
|
||||||
|
@item
|
||||||
@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB
|
@code{SHOW TABLE STATUS} doesn't yet provide that much information for BDB
|
||||||
tables.
|
tables.
|
||||||
@item
|
@item
|
||||||
@ -28310,6 +28353,7 @@ How big a @code{VARCHAR} column can be
|
|||||||
* mysql:: The command line tool
|
* mysql:: The command line tool
|
||||||
* mysqladmin:: Administering a @strong{MySQL} server
|
* mysqladmin:: Administering a @strong{MySQL} server
|
||||||
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
|
* mysqldump:: Dumping the structure and data from @strong{MySQL} databases and tables
|
||||||
|
* mysqlhotcopy:: Copying @strong{MySQL} Databases and Tables
|
||||||
* mysqlimport:: Importing data from text files
|
* mysqlimport:: Importing data from text files
|
||||||
* perror:: Displaying error messages
|
* perror:: Displaying error messages
|
||||||
* mysqlshow:: Showing databases, tables and columns
|
* mysqlshow:: Showing databases, tables and columns
|
||||||
@ -29167,17 +29211,22 @@ If you do @code{myslqadmin shutdown} on a socket (in other words, on a
|
|||||||
the computer where @code{mysqld} is running), @code{mysqladmin} will
|
the computer where @code{mysqld} is running), @code{mysqladmin} will
|
||||||
wait until the @strong{MySQL} @code{pid-file} is removed to ensure that
|
wait until the @strong{MySQL} @code{pid-file} is removed to ensure that
|
||||||
the @code{mysqld} server has stopped properly.
|
the @code{mysqld} server has stopped properly.
|
||||||
|
|
||||||
@cindex dumping, databases
|
@cindex dumping, databases
|
||||||
@cindex databases, dumping
|
@cindex databases, dumping
|
||||||
@cindex tables, dumping
|
@cindex tables, dumping
|
||||||
@cindex backing up, databases
|
@cindex backing up, databases
|
||||||
@node mysqldump, mysqlimport, mysqladmin, Tools
|
@node mysqldump, mysqlhotcopy, mysqladmin, Tools
|
||||||
@section Dumping the Structure and Data from MySQL Databases and Tables
|
@section Dumping the Structure and Data from MySQL Databases and Tables
|
||||||
|
|
||||||
@cindex @code{mysqldump}
|
@cindex @code{mysqldump}
|
||||||
Utility to dump a database or a collection of database for backup or
|
Utility to dump a database or a collection of database for backup or for
|
||||||
for transferring the data to another SQL server. The dump will contain SQL
|
transferring the data to another SQL server (not necessarily a MySQL
|
||||||
statements to create the table and/or populate the table:
|
server). The dump will contain SQL statements to create the table
|
||||||
|
and/or populate the table.
|
||||||
|
|
||||||
|
If you are doing a backup on the server, you should consider using
|
||||||
|
the @code{mysqlhotcopy} instead. @xref{mysqlhotcopy}.
|
||||||
|
|
||||||
@example
|
@example
|
||||||
shell> mysqldump [OPTIONS] database [tables]
|
shell> mysqldump [OPTIONS] database [tables]
|
||||||
@ -29350,12 +29399,79 @@ If all the databases are wanted, one can use:
|
|||||||
mysqldump --all-databases > all_databases.sql
|
mysqldump --all-databases > all_databases.sql
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
@cindex dumping, databases
|
||||||
|
@cindex databases, dumping
|
||||||
|
@cindex tables, dumping
|
||||||
|
@cindex backing up, databases
|
||||||
|
@node mysqlhotcopy, mysqlimport, mysqldump, Tools
|
||||||
|
@section Copying MySQL Databases and Tables
|
||||||
|
|
||||||
|
@code{mysqlhotcopy} is a perl script that uses @code{LOCK TABLES},
|
||||||
|
@code{FLUSH TABLES} and @code{cp} or @code{scp} to quickly make a backup
|
||||||
|
of a database. It's the fastest way to make a backup of the database,
|
||||||
|
but it can only be run on the same machine where the database directories
|
||||||
|
are.
|
||||||
|
|
||||||
|
@example
|
||||||
|
mysqlhotcopy db_name [/path/to/new_directory]
|
||||||
|
|
||||||
|
mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory
|
||||||
|
|
||||||
|
mysqlhotcopy db_name./regex/
|
||||||
|
@end example
|
||||||
|
|
||||||
|
@code{mysqlhotcopy} supports the following options:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item -?, --help
|
||||||
|
Display a helpscreen and exit
|
||||||
|
@item -u, --user=#
|
||||||
|
User for database login
|
||||||
|
@item -p, --password=#
|
||||||
|
Password to use when connecting to server
|
||||||
|
@item -P, --port=#
|
||||||
|
Port to use when connecting to local server
|
||||||
|
@item -S, --socket=#
|
||||||
|
Socket to use when connecting to local server
|
||||||
|
@item --allowold
|
||||||
|
Don't abort if target already exists (rename it _old)
|
||||||
|
@item --keepold
|
||||||
|
Don't delete previous (now renamed) target when done
|
||||||
|
@item --noindices
|
||||||
|
Don't include full index files in copy to make the backup smaller and faster
|
||||||
|
The indexes can later be reconstructed with @code{myisamchk -rq.}.
|
||||||
|
@item --method=#
|
||||||
|
Method for copy (@code{cp} or @code{scp}).
|
||||||
|
@item -q, --quiet
|
||||||
|
Be silent except for errors
|
||||||
|
@item --debug
|
||||||
|
Enable debug
|
||||||
|
@item -n, --dryrun
|
||||||
|
Report actions without doing them
|
||||||
|
@item --regexp=#
|
||||||
|
Copy all databases with names matching regexp
|
||||||
|
@item --suffix=#
|
||||||
|
Suffix for names of copied databases
|
||||||
|
@item --checkpoint=#
|
||||||
|
Insert checkpoint entry into specified db.table
|
||||||
|
@item --flushlog
|
||||||
|
Flush logs once all tables are locked.
|
||||||
|
@item --tmpdir=#
|
||||||
|
Temporary directory (instead of /tmp).
|
||||||
|
@end table
|
||||||
|
|
||||||
|
You can use 'perldoc mysqlhotcopy' to get a more complete documentation for
|
||||||
|
@code{mysqlhotcopy}.
|
||||||
|
|
||||||
|
@code{mysqlhotcopy} reads the group @code{[mysqlhotcopy]} from the option
|
||||||
|
files.
|
||||||
|
|
||||||
@cindex importing, data
|
@cindex importing, data
|
||||||
@cindex data, importing
|
@cindex data, importing
|
||||||
@cindex files, text
|
@cindex files, text
|
||||||
@cindex text files, importing
|
@cindex text files, importing
|
||||||
@cindex @code{mysqlimport}
|
@cindex @code{mysqlimport}
|
||||||
@node mysqlimport, perror, mysqldump, Tools
|
@node mysqlimport, perror, mysqlhotcopy, Tools
|
||||||
@section Importing Data from Text Files
|
@section Importing Data from Text Files
|
||||||
|
|
||||||
@code{mysqlimport} provides a command-line interface to the @code{LOAD DATA
|
@code{mysqlimport} provides a command-line interface to the @code{LOAD DATA
|
||||||
@ -32882,22 +32998,49 @@ expecting to store the full length of a @code{BLOB} into a table, you'll need
|
|||||||
to start the server with the @code{--set-variable=max_allowed_packet=16M}
|
to start the server with the @code{--set-variable=max_allowed_packet=16M}
|
||||||
option.
|
option.
|
||||||
|
|
||||||
|
@cindex aborted clients
|
||||||
@cindex aborted connection
|
@cindex aborted connection
|
||||||
@cindex connection, aborted
|
@cindex connection, aborted
|
||||||
@node Communication errors, Full table, Packet too large, Common errors
|
@node Communication errors, Full table, Packet too large, Common errors
|
||||||
@subsection Communication Errors / Aborted Connection
|
@subsection Communication Errors / Aborted Connection
|
||||||
|
|
||||||
If you find the error @code{Aborted connection} in the @code{hostname.err}
|
The server variable @code{Aborted_clients} is incremented when:
|
||||||
log file, this could be because of one of the following reasons:
|
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
The client had been sleeping more than @code{wait_timeout} without doing
|
The client program did not call @code{mysql_close()} before exit.
|
||||||
any requests. @xref{SHOW VARIABLES}.
|
@item
|
||||||
|
The client had been sleeping more than @code{wait_timeout} or
|
||||||
|
@code{interactive_timeout} without doing any requests. @xref{SHOW
|
||||||
|
VARIABLES}.
|
||||||
@item
|
@item
|
||||||
The client program ended abruptly in the middle of the transfer.
|
The client program ended abruptly in the middle of the transfer.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
When the above happens, the mysqld will write a note about an
|
||||||
|
@code{Aborted connection} in the @code{hostname.err}
|
||||||
|
|
||||||
|
The server variable @code{Aborted_connects} is incremented when:
|
||||||
|
|
||||||
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
The client program did not call @code{mysql_close()} before exit.
|
When a connection packet doesn't contain the right information.
|
||||||
|
@item
|
||||||
|
When the user didn't have privileges to connect to a database.
|
||||||
|
@item
|
||||||
|
When a user uses a wrong password.
|
||||||
|
@item
|
||||||
|
When it takes more than @code{connect_timeout} seconds to get
|
||||||
|
a connect package.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Note that the above could indicate that someone is trying to break into
|
||||||
|
your database!
|
||||||
|
|
||||||
|
@xref{SHOW VARIABLES}.
|
||||||
|
|
||||||
|
Other reason for problems with Aborted clients / Aborted connections.
|
||||||
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
Usage of duplex Ethernet protocol, both half and full with
|
Usage of duplex Ethernet protocol, both half and full with
|
||||||
Linux. Many Linux Ethernet drivers have this bug. You should test
|
Linux. Many Linux Ethernet drivers have this bug. You should test
|
||||||
@ -32915,6 +33058,7 @@ Faulty Ethernets or hubs or switches, cables ... This can be diagnosed
|
|||||||
properly only by replacing hardware.
|
properly only by replacing hardware.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
@cindex table is full
|
@cindex table is full
|
||||||
@node Full table, Cannot create, Communication errors, Common errors
|
@node Full table, Cannot create, Communication errors, Common errors
|
||||||
@subsection @code{The table is full} Error
|
@subsection @code{The table is full} Error
|
||||||
@ -33793,13 +33937,19 @@ mirror if needed. @code{LAST_INSERT_ID()} is also safe to use.
|
|||||||
|
|
||||||
Because @strong{MySQL} tables are stored as files, it is easy to do a
|
Because @strong{MySQL} tables are stored as files, it is easy to do a
|
||||||
backup. To get a consistent backup, do a @code{LOCK TABLES} on the
|
backup. To get a consistent backup, do a @code{LOCK TABLES} on the
|
||||||
relevant tables. @xref{LOCK TABLES, , @code{LOCK TABLES}}. You only need a
|
relevant tables followed by @code{FLUSH TABLES} for the tables.
|
||||||
read lock; this allows other threads to continue to query the tables while
|
@xref{LOCK TABLES, , @code{LOCK TABLES}}.
|
||||||
you are making a copy of the files in the database directory. If you want to
|
@xref{FLUSH, , @code{FLUSH}}.
|
||||||
make a SQL level backup of a table, you can use @code{SELECT INTO OUTFILE}.
|
You only need a read lock; this allows other threads to continue to
|
||||||
|
query the tables while you are making a copy of the files in the
|
||||||
|
database directory.
|
||||||
|
|
||||||
Another way to back up a database is to use the @code{mysqldump} program:
|
If you want to make a SQL level backup of a table, you can use
|
||||||
@xref{mysqldump}.
|
@code{SELECT INTO OUTFILE} or @code{BACKUP
|
||||||
|
TABLE}. @xref{SELECT}. @xref{BACKUP TABLE}.
|
||||||
|
|
||||||
|
Another way to back up a database is to use the @code{mysqldump} program or
|
||||||
|
the @code{mysqlhotcopy script}. @xref{mysqldump}. @xref{mysqlhotcopy}.
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
@ -33807,6 +33957,10 @@ Do a full backup of your databases:
|
|||||||
|
|
||||||
@example
|
@example
|
||||||
shell> mysqldump --tab=/path/to/some/dir --opt --full
|
shell> mysqldump --tab=/path/to/some/dir --opt --full
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
shell> mysqlhotcopy database /path/to/some/dir
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
You can also simply copy all table files (@file{*.frm}, @file{*.MYD}, and
|
You can also simply copy all table files (@file{*.frm}, @file{*.MYD}, and
|
||||||
@ -33823,16 +33977,23 @@ you executed @code{mysqldump}.
|
|||||||
@end enumerate
|
@end enumerate
|
||||||
|
|
||||||
If you have to restore something, try to recover your tables using
|
If you have to restore something, try to recover your tables using
|
||||||
@code{myisamchk -r} first. That should work in 99.9% of all cases. If
|
@code{REPAIR TABLE} or @code{myisamchk -r} first. That should work in
|
||||||
@code{myisamchk} fails, try the following procedure:
|
99.9% of all cases. If @code{myisamchk} fails, try the following
|
||||||
(This will only work if you have started @strong{MySQL} with
|
procedure: (This will only work if you have started @strong{MySQL} with
|
||||||
@code{--log-update}. @xref{Update log}.):
|
@code{--log-update}. @xref{Update log}.):
|
||||||
|
|
||||||
@enumerate
|
@enumerate
|
||||||
@item
|
@item
|
||||||
Restore the original @code{mysqldump} backup.
|
Restore the original @code{mysqldump} backup.
|
||||||
@item
|
@item
|
||||||
Execute the following command to re-run the updates in the update logs:
|
Execute the following command to re-run the updates in the binary log:
|
||||||
|
|
||||||
|
@example
|
||||||
|
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
|
||||||
|
@end example
|
||||||
|
|
||||||
|
If you are using the update log you can use:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
|
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
|
||||||
@end example
|
@end example
|
||||||
@ -40045,6 +40206,7 @@ developed a @strong{MySQL} feature themself or by giving us hardware for
|
|||||||
@multitable @columnfractions .3 .7
|
@multitable @columnfractions .3 .7
|
||||||
@item Va Linux / Andover.net @tab Replication
|
@item Va Linux / Andover.net @tab Replication
|
||||||
@item NuSphere @tab Editing of the @strong{MySQL} manual.
|
@item NuSphere @tab Editing of the @strong{MySQL} manual.
|
||||||
|
@item Stork Design studio @tab The MySQL web site in use between 1998-2000
|
||||||
@item Intel @tab Contributed to development on Windows and Linux platforms
|
@item Intel @tab Contributed to development on Windows and Linux platforms
|
||||||
@item Compaq @tab Contributed to Development on Linux-alpha
|
@item Compaq @tab Contributed to Development on Linux-alpha
|
||||||
@item SWSoft @tab Development on the embedded @code{mysqld} version.
|
@item SWSoft @tab Development on the embedded @code{mysqld} version.
|
||||||
@ -40143,6 +40305,10 @@ though, so Version 3.23 is not released as a stable version yet.
|
|||||||
@appendixsubsec Changes in release 3.23.31
|
@appendixsubsec Changes in release 3.23.31
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
Fixed bug when using expression of type
|
||||||
|
@code{SELECT ... FROM t1 left join t2 on (t1.a=t2.a) WHERE t1.a=t2.a}. In this
|
||||||
|
case the test in the @code{WHERE} clause was wrongly optimized away.
|
||||||
|
@item
|
||||||
Fixed bug in @code{MyISAM} when deleting keys with possible @code{NULL}
|
Fixed bug in @code{MyISAM} when deleting keys with possible @code{NULL}
|
||||||
values, but the first key-column was not a prefix-compressed text column.
|
values, but the first key-column was not a prefix-compressed text column.
|
||||||
@item
|
@item
|
||||||
@ -40159,6 +40325,8 @@ Added @code{Threads_created} status variable to @code{mysqld}.
|
|||||||
@appendixsubsec Changes in release 3.23.30
|
@appendixsubsec Changes in release 3.23.30
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
|
Fixed that @code{myisamdump} works against old mysqld servers.
|
||||||
|
@item
|
||||||
Fixed that @code{myisamchk -k#} works again.
|
Fixed that @code{myisamchk -k#} works again.
|
||||||
@item
|
@item
|
||||||
Fixed a problem with replication when the binary log file went over 2G
|
Fixed a problem with replication when the binary log file went over 2G
|
||||||
@ -44720,6 +44888,13 @@ will probably be ignored).
|
|||||||
Doing a @code{LOCK TABLE ..} and @code{FLUSH TABLES ..} doesn't
|
Doing a @code{LOCK TABLE ..} and @code{FLUSH TABLES ..} doesn't
|
||||||
guarantee that there isn't a half-finished transaction in progress on the
|
guarantee that there isn't a half-finished transaction in progress on the
|
||||||
table.
|
table.
|
||||||
|
|
||||||
|
@item
|
||||||
|
BDB tables are a bit slow to open from this. If you have many BDB tables
|
||||||
|
in a database, it will take a long time to use the @code{mysql} client
|
||||||
|
on the database if you are not using the @code{-A} option or if you are
|
||||||
|
using @code{rehash}. This is especially notable when you have a big table
|
||||||
|
cache.
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
The following problems are known and will be fixed in due time:
|
The following problems are known and will be fixed in due time:
|
||||||
@ -44974,6 +45149,10 @@ Secure connections (with SSL).
|
|||||||
Extend the optimizer to be able to optimize some @code{ORDER BY key_name DESC}
|
Extend the optimizer to be able to optimize some @code{ORDER BY key_name DESC}
|
||||||
queries.
|
queries.
|
||||||
@item
|
@item
|
||||||
|
@code{SHOW COLUMNS FROM table_name} (used by @code{mysql} client to allow
|
||||||
|
expansions of column names) should not open the table, but only the
|
||||||
|
definition file. This will require less memory and be much faster.
|
||||||
|
@item
|
||||||
New key cache
|
New key cache
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@ -45565,20 +45744,20 @@ Stop the mysqld daemon (with @code{mysqladmin shutdown})
|
|||||||
Check all tables with @code{myisamchk -s database/*.MYI}. Repair any
|
Check all tables with @code{myisamchk -s database/*.MYI}. Repair any
|
||||||
wrong tables with @code{myisamchk -r database/table.MYI}.
|
wrong tables with @code{myisamchk -r database/table.MYI}.
|
||||||
@item
|
@item
|
||||||
Start @code{mysqld} with @code{--log-update}. @xref{Update log}.
|
Start @code{mysqld} with @code{--log-binary}. @xref{Binary log}.
|
||||||
@item
|
@item
|
||||||
When you have gotten a crashed table, stop the @code{mysqld server}.
|
When you have gotten a crashed table, stop the @code{mysqld server}.
|
||||||
@item
|
@item
|
||||||
Restore the backup.
|
Restore the backup.
|
||||||
@item
|
@item
|
||||||
Restart the @code{mysqld} server @strong{without} @code{--log-update}
|
Restart the @code{mysqld} server @strong{without} @code{--log-binary}
|
||||||
@item
|
@item
|
||||||
Re-execute the commands with @code{mysql < update-log}. The update log
|
Re-execute the commands with @code{mysqlbinlog update-log-file | mysql}.
|
||||||
is saved in the @strong{MySQL} database directory with the name
|
The update log is saved in the @strong{MySQL} database directory with
|
||||||
@code{your-hostname.#}.
|
the name @code{hostname-bin.#}.
|
||||||
@item
|
@item
|
||||||
If the tables are corrupted again, you have found reproducible bug
|
If the tables are corrupted again, you have found reproducible bug
|
||||||
in the @code{ISAM} code! FTP the tables and the update log to
|
in the @code{MyISAM} code! FTP the tables and the update log to
|
||||||
@uref{ftp://support.mysql.com/pub/mysql/secret} and we will fix this as soon as
|
@uref{ftp://support.mysql.com/pub/mysql/secret} and we will fix this as soon as
|
||||||
possible!
|
possible!
|
||||||
@end itemize
|
@end itemize
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
#include "my_readline.h"
|
#include "my_readline.h"
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
const char *VER="11.10";
|
const char *VER="11.11";
|
||||||
|
|
||||||
gptr sql_alloc(unsigned size); // Don't use mysqld alloc for these
|
gptr sql_alloc(unsigned size); // Don't use mysqld alloc for these
|
||||||
void sql_element_free(void *ptr);
|
void sql_element_free(void *ptr);
|
||||||
@ -1192,7 +1192,8 @@ You can turn off this feature to get a quicker startup with -A\n\n");
|
|||||||
field_names=0;
|
field_names=0;
|
||||||
|
|
||||||
/* hash all field names, both with the table prefix and without it */
|
/* hash all field names, both with the table prefix and without it */
|
||||||
if (!tables) { /* no tables */
|
if (!tables) /* no tables */
|
||||||
|
{
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
mysql_data_seek(tables,0);
|
mysql_data_seek(tables,0);
|
||||||
@ -1201,7 +1202,6 @@ You can turn off this feature to get a quicker startup with -A\n\n");
|
|||||||
MYF(MY_WME));
|
MYF(MY_WME));
|
||||||
if (!field_names)
|
if (!field_names)
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
field_names[mysql_num_rows(tables)]='\0';
|
|
||||||
i=0;
|
i=0;
|
||||||
while ((table_row=mysql_fetch_row(tables)))
|
while ((table_row=mysql_fetch_row(tables)))
|
||||||
{
|
{
|
||||||
@ -1229,10 +1229,14 @@ You can turn off this feature to get a quicker startup with -A\n\n");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
tee_fprintf(stdout,
|
tee_fprintf(stdout,
|
||||||
"Didn't find any fields in table '%s'\n",table_row[0]);
|
"Didn't find any fields in table '%s'\n",table_row[0]);
|
||||||
|
field_names[i]=0;
|
||||||
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
field_names[i]=0; // End pointer
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2018,11 +2022,11 @@ com_use(String *buffer __attribute__((unused)), char *line)
|
|||||||
if (mysql_select_db(&mysql,tmp))
|
if (mysql_select_db(&mysql,tmp))
|
||||||
return put_info(mysql_error(&mysql),INFO_ERROR,mysql_errno(&mysql));
|
return put_info(mysql_error(&mysql),INFO_ERROR,mysql_errno(&mysql));
|
||||||
}
|
}
|
||||||
|
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
current_db=my_strdup(tmp,MYF(MY_WME));
|
||||||
#ifdef HAVE_READLINE
|
#ifdef HAVE_READLINE
|
||||||
build_completion_hash(no_rehash,1);
|
build_completion_hash(no_rehash,1);
|
||||||
#endif
|
#endif
|
||||||
my_free(current_db,MYF(MY_ALLOW_ZERO_PTR));
|
|
||||||
current_db=my_strdup(tmp,MYF(MY_WME));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1241,7 +1241,7 @@ MYSQL_HAVE_FIONREAD
|
|||||||
MYSQL_HAVE_TIOCSTAT
|
MYSQL_HAVE_TIOCSTAT
|
||||||
MYSQL_STRUCT_DIRENT_D_INO
|
MYSQL_STRUCT_DIRENT_D_INO
|
||||||
MYSQL_TYPE_SIGHANDLER
|
MYSQL_TYPE_SIGHANDLER
|
||||||
if test $with_named_curses = "no"
|
if test "$with_named_curses" = "no"
|
||||||
then
|
then
|
||||||
MYSQL_CHECK_LIB_TERMCAP
|
MYSQL_CHECK_LIB_TERMCAP
|
||||||
else
|
else
|
||||||
|
@ -196,3 +196,7 @@ Changes done to this distrubtion (pthreads-1_60_beta6) by Monty (monty@tcx.se)
|
|||||||
00.10.18 by Monty (monty@mysql.com)
|
00.10.18 by Monty (monty@mysql.com)
|
||||||
- Added patch by Dave Huang <khym@bga.com> to fix problem with date/time
|
- Added patch by Dave Huang <khym@bga.com> to fix problem with date/time
|
||||||
on NETBSD/Alpha.
|
on NETBSD/Alpha.
|
||||||
|
|
||||||
|
01.01.11 by Monty (monty@mysql.com)
|
||||||
|
- Added patch by Allen Briggs <briggs@ninthwonder.com> for
|
||||||
|
Apple PowerMac 8500 w/ G3 upgrade running NetBSD/macppc
|
||||||
|
3
mit-pthreads/config/config.guess
vendored
3
mit-pthreads/config/config.guess
vendored
@ -295,7 +295,8 @@ EOF
|
|||||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||||
exit 0 ;;
|
exit 0 ;;
|
||||||
*:NetBSD:*:*)
|
*:NetBSD:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
UNAME_PROCESSOR=`uname -p 2>/dev/null` || UNAME_PROCESSOR=$UNAME_MACHINE
|
||||||
|
echo ${UNAME_PROCESSOR}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||||
exit 0 ;;
|
exit 0 ;;
|
||||||
*:OpenBSD:*:*)
|
*:OpenBSD:*:*)
|
||||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||||
|
6
mit-pthreads/config/configure
vendored
6
mit-pthreads/config/configure
vendored
@ -1298,6 +1298,12 @@ case $host in
|
|||||||
# hpux-9.03.mk seems to be missing; what should this be?
|
# hpux-9.03.mk seems to be missing; what should this be?
|
||||||
except="fork"
|
except="fork"
|
||||||
;;
|
;;
|
||||||
|
powerpc-*-netbsd1.*)
|
||||||
|
name=powerpc-netbsd
|
||||||
|
sysincludes=netbsd-1.1
|
||||||
|
except="fork lseek ftruncate pipe fstat"
|
||||||
|
available_syscalls="sigprocmask sigaction sigsuspend"
|
||||||
|
;;
|
||||||
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
|
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
|
||||||
name=sparc-sunos-4.1.3
|
name=sparc-sunos-4.1.3
|
||||||
sysincludes=sunos-4.1.3
|
sysincludes=sunos-4.1.3
|
||||||
|
@ -175,6 +175,12 @@ changequote([,])dnl
|
|||||||
# hpux-9.03.mk seems to be missing; what should this be?
|
# hpux-9.03.mk seems to be missing; what should this be?
|
||||||
except="fork"
|
except="fork"
|
||||||
;;
|
;;
|
||||||
|
powerpc-*-netbsd1.*)
|
||||||
|
name=powerpc-netbsd
|
||||||
|
sysincludes=netbsd-1.1
|
||||||
|
except="fork lseek ftruncate pipe fstat"
|
||||||
|
available_syscalls="sigprocmask sigaction sigsuspend"
|
||||||
|
;;
|
||||||
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
|
sparc-*-sunos4.1.3* | sparc-*-sunos4.1.4*)
|
||||||
name=sparc-sunos-4.1.3
|
name=sparc-sunos-4.1.3
|
||||||
sysincludes=sunos-4.1.3
|
sysincludes=sunos-4.1.3
|
||||||
|
227
mit-pthreads/machdep/engine-powerpc-netbsd.c
Normal file
227
mit-pthreads/machdep/engine-powerpc-netbsd.c
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
/* ==== machdep.c ============================================================
|
||||||
|
* Copyright (c) 1993, 1994 Chris Provenzano, proven@athena.mit.edu
|
||||||
|
*
|
||||||
|
* Description : Machine dependent functions for NetBSD/PowerPC (1.5+)
|
||||||
|
*
|
||||||
|
* 1.00 93/08/04 proven
|
||||||
|
* -Started coding this file.
|
||||||
|
*
|
||||||
|
* 2001/01/10 briggs
|
||||||
|
* -Modified to make it go with NetBSD/PowerPC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static const char rcsid[] = "engine-alpha-osf1.c,v 1.4.4.1 1995/12/13 05:41:37 proven Exp";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_pthread_start()
|
||||||
|
*/
|
||||||
|
void machdep_pthread_start(void)
|
||||||
|
{
|
||||||
|
context_switch_done();
|
||||||
|
pthread_sched_resume ();
|
||||||
|
|
||||||
|
/* XXXMLG
|
||||||
|
* This is EXTREMELY bogus, but it seems that this function is called
|
||||||
|
* with the pthread kernel locked. If this happens, __errno() will
|
||||||
|
* return the wrong address until after the first context switch.
|
||||||
|
*
|
||||||
|
* Clearly there is a leak of pthread_kernel somewhere, but until
|
||||||
|
* it is found, we force a context switch here, just before calling
|
||||||
|
* the thread start routine. When we return from pthread_yield
|
||||||
|
* the kernel will be unlocked.
|
||||||
|
*/
|
||||||
|
pthread_yield();
|
||||||
|
|
||||||
|
/* Run current threads start routine with argument */
|
||||||
|
pthread_exit(pthread_run->machdep_data.start_routine
|
||||||
|
(pthread_run->machdep_data.start_argument));
|
||||||
|
|
||||||
|
/* should never reach here */
|
||||||
|
PANIC();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* __machdep_pthread_create()
|
||||||
|
*/
|
||||||
|
void __machdep_pthread_create(struct machdep_pthread *machdep_pthread,
|
||||||
|
void *(* start_routine)(void *), void *start_argument,
|
||||||
|
long stack_size, long nsec, long flags)
|
||||||
|
{
|
||||||
|
machdep_pthread->start_routine = start_routine;
|
||||||
|
machdep_pthread->start_argument = start_argument;
|
||||||
|
|
||||||
|
machdep_pthread->machdep_timer.it_value.tv_sec = 0;
|
||||||
|
machdep_pthread->machdep_timer.it_interval.tv_sec = 0;
|
||||||
|
machdep_pthread->machdep_timer.it_interval.tv_usec = 0;
|
||||||
|
machdep_pthread->machdep_timer.it_value.tv_usec = nsec / 1000;
|
||||||
|
|
||||||
|
/* Set up new stack frame so that it looks like it returned from a
|
||||||
|
longjmp() to the beginning of machdep_pthread_start(). */
|
||||||
|
/* state is sigmask, then r8-r31 where r11 is the LR
|
||||||
|
* So, istate[3] is r10, which is the SP
|
||||||
|
* So, istate[4] is r11, which is the LR
|
||||||
|
* So, istate[5] is r12, which is the CR
|
||||||
|
*/
|
||||||
|
machdep_pthread->machdep_istate[4] = (long)machdep_pthread_start;
|
||||||
|
machdep_pthread->machdep_istate[5] = 0;
|
||||||
|
|
||||||
|
/* PowerPC stack starts high and builds down, and needs to be 16-byte
|
||||||
|
aligned. */
|
||||||
|
machdep_pthread->machdep_istate[3] =
|
||||||
|
((long) machdep_pthread->machdep_stack + stack_size) & ~0xf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_save_state()
|
||||||
|
*/
|
||||||
|
int machdep_save_state(void)
|
||||||
|
{
|
||||||
|
return( _setjmp(pthread_run->machdep_data.machdep_istate) );
|
||||||
|
}
|
||||||
|
|
||||||
|
void machdep_restore_state(void)
|
||||||
|
{
|
||||||
|
_longjmp(pthread_run->machdep_data.machdep_istate, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void machdep_save_float_state (struct pthread *pthread)
|
||||||
|
{
|
||||||
|
__machdep_save_fp_state(pthread->machdep_data.machdep_fstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void machdep_restore_float_state (void)
|
||||||
|
{
|
||||||
|
__machdep_restore_fp_state(pthread_run->machdep_data.machdep_fstate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_set_thread_timer()
|
||||||
|
*/
|
||||||
|
void machdep_set_thread_timer(struct machdep_pthread *machdep_pthread)
|
||||||
|
{
|
||||||
|
if (setitimer(ITIMER_VIRTUAL, &(machdep_pthread->machdep_timer), NULL)) {
|
||||||
|
PANIC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_unset_thread_timer()
|
||||||
|
*/
|
||||||
|
void machdep_unset_thread_timer(struct machdep_pthread *machdep_pthread)
|
||||||
|
{
|
||||||
|
struct itimerval zeroval = { { 0, 0 }, { 0, 0} };
|
||||||
|
|
||||||
|
if (setitimer(ITIMER_VIRTUAL, &zeroval, NULL)) {
|
||||||
|
PANIC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_pthread_cleanup()
|
||||||
|
*/
|
||||||
|
void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread)
|
||||||
|
{
|
||||||
|
return(machdep_pthread->machdep_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *machdep_pthread_cleanup(struct machdep_pthread *machdep_pthread);
|
||||||
|
void machdep_pthread_start(void);
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* __machdep_stack_free()
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
__machdep_stack_free(void * stack)
|
||||||
|
{
|
||||||
|
free(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* __machdep_stack_alloc()
|
||||||
|
*/
|
||||||
|
void *
|
||||||
|
__machdep_stack_alloc(size_t size)
|
||||||
|
{
|
||||||
|
return(malloc(size));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_creat()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
machdep_sys_creat(char * path, int mode)
|
||||||
|
{
|
||||||
|
return(machdep_sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_wait3()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
machdep_sys_wait3(int * b, int c, int *d)
|
||||||
|
{
|
||||||
|
return(machdep_sys_wait4(0, b, c, d));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_waitpid()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
machdep_sys_waitpid(int a, int * b, int c)
|
||||||
|
{
|
||||||
|
return(machdep_sys_wait4(a, b, c, NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_getdtablesize()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
machdep_sys_getdtablesize(void)
|
||||||
|
{
|
||||||
|
return(sysconf(_SC_OPEN_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_lseek()
|
||||||
|
*/
|
||||||
|
off_t
|
||||||
|
machdep_sys_lseek(int fd, off_t offset, int whence)
|
||||||
|
{
|
||||||
|
return(__syscall((quad_t)SYS_lseek, fd, 0, offset, whence));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
machdep_sys_ftruncate( int fd, off_t length)
|
||||||
|
{
|
||||||
|
quad_t q;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
q = __syscall((quad_t)SYS_ftruncate, fd,0, length);
|
||||||
|
if( /* LINTED constant */ sizeof( quad_t ) == sizeof( register_t ) ||
|
||||||
|
/* LINTED constant */ BYTE_ORDER == LITTLE_ENDIAN )
|
||||||
|
rv = (int)q;
|
||||||
|
else
|
||||||
|
rv = (int)((u_quad_t)q >> 32);
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ==========================================================================
|
||||||
|
* machdep_sys_getdirentries()
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
machdep_sys_getdirentries(int fd, char * buf, int len, int * seek)
|
||||||
|
{
|
||||||
|
return(machdep_sys_getdents(fd, buf, len));
|
||||||
|
}
|
109
mit-pthreads/machdep/engine-powerpc-netbsd.h
Normal file
109
mit-pthreads/machdep/engine-powerpc-netbsd.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/* ==== machdep.h ============================================================
|
||||||
|
* Copyright (c) 1994 Chris Provenzano (proven@athena.mit.edu) and
|
||||||
|
* Ken Raeburn (raeburn@mit.edu).
|
||||||
|
*
|
||||||
|
* engine-alpha-osf1.h,v 1.4.4.1 1995/12/13 05:41:42 proven Exp
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include <sys/signal.h> /* for _NSIG */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The first machine dependent functions are the SEMAPHORES
|
||||||
|
* needing the test and set instruction.
|
||||||
|
*/
|
||||||
|
#define SEMAPHORE_CLEAR 0
|
||||||
|
#define SEMAPHORE_SET 0xffff
|
||||||
|
|
||||||
|
#define SEMAPHORE_TEST_AND_SET(lock) \
|
||||||
|
({ \
|
||||||
|
volatile long t1, temp = SEMAPHORE_SET; \
|
||||||
|
__asm__ volatile( \
|
||||||
|
"1: lwarx %0,0,%1; \
|
||||||
|
cmpwi %0, 0; \
|
||||||
|
bne 2f; \
|
||||||
|
stwcx. %2,0,%1; \
|
||||||
|
bne- 1b; \
|
||||||
|
2: " \
|
||||||
|
:"=r" (t1) \
|
||||||
|
:"m" (lock), "r" (temp)); \
|
||||||
|
t1; \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define SEMAPHORE_RESET(lock) *lock = SEMAPHORE_CLEAR
|
||||||
|
|
||||||
|
/*
|
||||||
|
* New types
|
||||||
|
*/
|
||||||
|
typedef int semaphore;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sigset_t macros
|
||||||
|
*/
|
||||||
|
#define SIG_ANY(sig) (sig)
|
||||||
|
#define SIGMAX (_NSIG-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* New Strutures
|
||||||
|
*/
|
||||||
|
struct machdep_pthread {
|
||||||
|
void *(*start_routine)(void *);
|
||||||
|
void *start_argument;
|
||||||
|
void *machdep_stack;
|
||||||
|
struct itimerval machdep_timer;
|
||||||
|
jmp_buf machdep_istate;
|
||||||
|
unsigned long machdep_fstate[66];
|
||||||
|
/* 64-bit fp regs 0-31 + fpscr */
|
||||||
|
/* We pretend the fpscr is 64 bits */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Static machdep_pthread initialization values.
|
||||||
|
* For initial thread only.
|
||||||
|
*/
|
||||||
|
#define MACHDEP_PTHREAD_INIT \
|
||||||
|
{ NULL, NULL, NULL, { { 0, 0 }, { 0, 100000 } }, { 0 }, { 0 } }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Minimum stack size
|
||||||
|
*/
|
||||||
|
#define PTHREAD_STACK_MIN 2048
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some fd flag defines that are necessary to distinguish between posix
|
||||||
|
* behavior and bsd4.3 behavior.
|
||||||
|
*/
|
||||||
|
#define __FD_NONBLOCK O_NONBLOCK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* New functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
|
||||||
|
#if defined(PTHREAD_KERNEL)
|
||||||
|
|
||||||
|
#define __machdep_stack_get(x) (x)->machdep_stack
|
||||||
|
#define __machdep_stack_set(x, y) (x)->machdep_stack = y
|
||||||
|
#define __machdep_stack_repl(x, y) \
|
||||||
|
{ \
|
||||||
|
if ((stack = __machdep_stack_get(x))) { \
|
||||||
|
__machdep_stack_free(stack); \
|
||||||
|
} \
|
||||||
|
__machdep_stack_set(x, y); \
|
||||||
|
}
|
||||||
|
|
||||||
|
int machdep_save_state(void);
|
||||||
|
|
||||||
|
void __machdep_save_fp_state(unsigned long *);
|
||||||
|
void __machdep_restore_fp_state(unsigned long *);
|
||||||
|
void *__machdep_stack_alloc(size_t);
|
||||||
|
void __machdep_stack_free(void *);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__END_DECLS
|
185
mit-pthreads/machdep/syscall-powerpc-netbsd.S
Normal file
185
mit-pthreads/machdep/syscall-powerpc-netbsd.S
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include <machine/asm.h>
|
||||||
|
#define COMPAT_43
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#ifndef __CONCAT
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#endif
|
||||||
|
#define CONCAT __CONCAT
|
||||||
|
|
||||||
|
#undef SYSCALL
|
||||||
|
|
||||||
|
/* Kernel syscall interface:
|
||||||
|
Input:
|
||||||
|
0 - system call number
|
||||||
|
3-8 - arguments, as in C
|
||||||
|
Output:
|
||||||
|
so - (summary overflow) clear iff successful
|
||||||
|
|
||||||
|
This macro is similar to SYSCALL in asm.h, but not completely.
|
||||||
|
There's room for optimization, if we assume this will continue to
|
||||||
|
be assembled as one file.
|
||||||
|
|
||||||
|
This macro expansions does not include the return instruction.
|
||||||
|
If there's no other work to be done, use something like:
|
||||||
|
SYSCALL(foo) ; ret
|
||||||
|
If there is other work to do (in fork, maybe?), do it after the
|
||||||
|
SYSCALL invocation. */
|
||||||
|
|
||||||
|
ENTRY(machdep_cerror)
|
||||||
|
mflr 0 # Save LR in 0
|
||||||
|
stwu 1,-16(1) # allocate new stack frame
|
||||||
|
stw 0,20(1) # Stash 0 in stack
|
||||||
|
stw 31,8(1) # Stash 31 in stack (since it's callee-saved
|
||||||
|
mr 31,3 # and we stash return there)
|
||||||
|
bl PIC_PLT(_C_LABEL(__errno))
|
||||||
|
stw 31,0(3) # *errno() = err
|
||||||
|
lwz 0,20(1) # Restore LR from stack to 0
|
||||||
|
neg 3,31 # return -errno to 3
|
||||||
|
lwz 31,8(1) # Restore 31 from stack
|
||||||
|
mtlr 0
|
||||||
|
la 1,16(1) # Restore stack frame
|
||||||
|
li 4,-1 # Put -1 in r4 for those syscalls that return
|
||||||
|
blr # two values
|
||||||
|
|
||||||
|
/* The fork system call is special... */
|
||||||
|
ENTRY(machdep_sys_fork)
|
||||||
|
li 0, SYS_fork
|
||||||
|
sc
|
||||||
|
bso PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
addi 4,4,-1
|
||||||
|
blr
|
||||||
|
|
||||||
|
/* The pipe system call is special... */
|
||||||
|
ENTRY(machdep_sys_pipe)
|
||||||
|
mr 5,3
|
||||||
|
li 0,SYS_pipe
|
||||||
|
sc
|
||||||
|
bso PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
stw 3,0(5) # Success, store fds
|
||||||
|
stw 4,4(5)
|
||||||
|
li 3,0
|
||||||
|
blr # And return 0
|
||||||
|
|
||||||
|
#ifndef SYS___sigsuspend14
|
||||||
|
/* The sigsuspend system call is special... */
|
||||||
|
ENTRY(machdep_sys_sigsuspend)
|
||||||
|
lwz 3,0(3)
|
||||||
|
li 0,SYS_compat_13_sigsuspend13
|
||||||
|
sc
|
||||||
|
b PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
#endif /* SYS_sigsuspend14 */
|
||||||
|
|
||||||
|
#ifndef SYS___sigprocmask14
|
||||||
|
/* The sigprocmask system call is special... */
|
||||||
|
ENTRY(machdep_sys_sigprocmask)
|
||||||
|
or. 4,4,4 # Set == NULL ?
|
||||||
|
li 6,1 # how = SIG_BLOCK
|
||||||
|
beq Ldoit
|
||||||
|
lwz 4,0(4) # if not, replace it in r4 with #set
|
||||||
|
mr 6,3
|
||||||
|
Ldoit: mr 3,6 # ... using sigprocmask(SIG_BLOCK)
|
||||||
|
li 0,SYS_compat_13_sigprocmask13
|
||||||
|
sc
|
||||||
|
bso PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
or. 5,5,5 # Check to see if oset requested
|
||||||
|
beq Ldone # if oset != NULL
|
||||||
|
stw 3,0(5) # *oset = oldmask
|
||||||
|
Ldone:
|
||||||
|
li 3,0 # return 0
|
||||||
|
blr
|
||||||
|
#endif /* SYS_sigprocmask14 */
|
||||||
|
|
||||||
|
/* More stuff ... */
|
||||||
|
|
||||||
|
/* For fstat() we actually syscall fstat13. */
|
||||||
|
ENTRY(machdep_sys_fstat)
|
||||||
|
li 0, SYS___fstat13
|
||||||
|
sc
|
||||||
|
bnslr
|
||||||
|
b PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
|
||||||
|
/* Do we need to save the entire floating point state? I think so... */
|
||||||
|
ENTRY(__machdep_save_fp_state)
|
||||||
|
stwu 1,-8(1)
|
||||||
|
stw 3,4(1)
|
||||||
|
stfd 0,0(3)
|
||||||
|
stfdu 1,8(3)
|
||||||
|
stfdu 2,8(3)
|
||||||
|
stfdu 3,8(3)
|
||||||
|
stfdu 4,8(3)
|
||||||
|
stfdu 5,8(3)
|
||||||
|
stfdu 6,8(3)
|
||||||
|
stfdu 7,8(3)
|
||||||
|
stfdu 8,8(3)
|
||||||
|
stfdu 9,8(3)
|
||||||
|
stfdu 10,8(3)
|
||||||
|
stfdu 11,8(3)
|
||||||
|
stfdu 12,8(3)
|
||||||
|
stfdu 13,8(3)
|
||||||
|
stfdu 14,8(3)
|
||||||
|
stfdu 15,8(3)
|
||||||
|
stfdu 16,8(3)
|
||||||
|
stfdu 17,8(3)
|
||||||
|
stfdu 18,8(3)
|
||||||
|
stfdu 19,8(3)
|
||||||
|
stfdu 20,8(3)
|
||||||
|
stfdu 21,8(3)
|
||||||
|
stfdu 22,8(3)
|
||||||
|
stfdu 23,8(3)
|
||||||
|
stfdu 24,8(3)
|
||||||
|
stfdu 25,8(3)
|
||||||
|
stfdu 26,8(3)
|
||||||
|
stfdu 27,8(3)
|
||||||
|
stfdu 28,8(3)
|
||||||
|
stfdu 29,8(3)
|
||||||
|
stfdu 30,8(3)
|
||||||
|
stfdu 31,8(3)
|
||||||
|
mffs 0
|
||||||
|
stfdu 0,8(3)
|
||||||
|
lwz 3,4(1)
|
||||||
|
lwz 1,0(1)
|
||||||
|
blr
|
||||||
|
|
||||||
|
ENTRY(__machdep_restore_fp_state)
|
||||||
|
stwu 1,-12(1)
|
||||||
|
stw 3,4(1)
|
||||||
|
stw 4,8(1)
|
||||||
|
mr 4,3
|
||||||
|
lfdu 1,8(3)
|
||||||
|
lfdu 2,8(3)
|
||||||
|
lfdu 3,8(3)
|
||||||
|
lfdu 4,8(3)
|
||||||
|
lfdu 5,8(3)
|
||||||
|
lfdu 6,8(3)
|
||||||
|
lfdu 7,8(3)
|
||||||
|
lfdu 8,8(3)
|
||||||
|
lfdu 9,8(3)
|
||||||
|
lfdu 10,8(3)
|
||||||
|
lfdu 11,8(3)
|
||||||
|
lfdu 12,8(3)
|
||||||
|
lfdu 13,8(3)
|
||||||
|
lfdu 14,8(3)
|
||||||
|
lfdu 15,8(3)
|
||||||
|
lfdu 16,8(3)
|
||||||
|
lfdu 17,8(3)
|
||||||
|
lfdu 18,8(3)
|
||||||
|
lfdu 19,8(3)
|
||||||
|
lfdu 20,8(3)
|
||||||
|
lfdu 21,8(3)
|
||||||
|
lfdu 22,8(3)
|
||||||
|
lfdu 23,8(3)
|
||||||
|
lfdu 24,8(3)
|
||||||
|
lfdu 25,8(3)
|
||||||
|
lfdu 26,8(3)
|
||||||
|
lfdu 27,8(3)
|
||||||
|
lfdu 28,8(3)
|
||||||
|
lfdu 29,8(3)
|
||||||
|
lfdu 30,8(3)
|
||||||
|
lfdu 31,8(3)
|
||||||
|
lfdu 0,8(3)
|
||||||
|
mtfsf 127,0
|
||||||
|
lfd 0,0(4)
|
||||||
|
lwz 3,4(1)
|
||||||
|
lwz 4,8(1)
|
||||||
|
lwz 1,0(1)
|
||||||
|
blr
|
45
mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
Normal file
45
mit-pthreads/machdep/syscall-template-powerpc-netbsd.S
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <machine/asm.h>
|
||||||
|
#define COMPAT_43
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
|
||||||
|
#ifdef SYS___sigsuspend14
|
||||||
|
#define SYS_sigsuspend SYS___sigsuspend14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SYS___sigaction14
|
||||||
|
#define SYS_sigaction SYS___sigaction14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SYS___sigprocmask14
|
||||||
|
#define SYS_sigprocmask SYS___sigprocmask14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#undef SYSCALL
|
||||||
|
|
||||||
|
/* Kernel syscall interface:
|
||||||
|
Input:
|
||||||
|
0 - system call number
|
||||||
|
3-8 - arguments, as in C
|
||||||
|
Output:
|
||||||
|
so - (summary overflow) clear iff successful
|
||||||
|
|
||||||
|
This macro is similar to SYSCALL in asm.h, but not completely.
|
||||||
|
There's room for optimization, if we assume this will continue to
|
||||||
|
be assembled as one file.
|
||||||
|
|
||||||
|
This macro expansions does not include the return instruction.
|
||||||
|
If there's no other work to be done, use something like:
|
||||||
|
SYSCALL(foo) ; ret
|
||||||
|
If there is other work to do (in fork, maybe?), do it after the
|
||||||
|
SYSCALL invocation. */
|
||||||
|
|
||||||
|
#define SYSCALL(x) \
|
||||||
|
ENTRY(machdep_sys_ ## x) \
|
||||||
|
li 0, SYS_ ## x ; \
|
||||||
|
sc ; \
|
||||||
|
bnslr ; \
|
||||||
|
b PIC_PLT(_C_LABEL(machdep_cerror))
|
||||||
|
|
||||||
|
#define XSYSCALL(x) SYSCALL(x) ; blr
|
||||||
|
|
||||||
|
XSYSCALL(SYSCALL_NAME)
|
@ -35,6 +35,14 @@ grp a c id a c d
|
|||||||
1 1 a 1 1 a 1
|
1 1 a 1 1 a 1
|
||||||
2 2 b NULL NULL NULL NULL
|
2 2 b NULL NULL NULL NULL
|
||||||
2 3 c NULL NULL NULL NULL
|
2 3 c NULL NULL NULL NULL
|
||||||
|
3 4 E 3 4 A 4
|
||||||
|
3 5 C 3 5 B 5
|
||||||
|
3 6 D 3 6 C 6
|
||||||
|
NULL NULL NULL NULL NULL NULL
|
||||||
|
grp a c id a c d
|
||||||
|
1 1 a 1 1 a 1
|
||||||
|
2 2 b NULL NULL NULL NULL
|
||||||
|
2 3 c NULL NULL NULL NULL
|
||||||
3 4 E NULL NULL NULL NULL
|
3 4 E NULL NULL NULL NULL
|
||||||
3 5 C NULL NULL NULL NULL
|
3 5 C NULL NULL NULL NULL
|
||||||
3 6 D NULL NULL NULL NULL
|
3 6 D NULL NULL NULL NULL
|
||||||
|
@ -18,6 +18,7 @@ select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c;
|
|||||||
select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
|
select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) };
|
||||||
select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
|
select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2;
|
||||||
select t1.*,t2.* from t1 left join t2 using (a);
|
select t1.*,t2.* from t1 left join t2 using (a);
|
||||||
|
select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a;
|
||||||
select t1.*,t2.* from t1 left join t2 using (a,c);
|
select t1.*,t2.* from t1 left join t2 using (a,c);
|
||||||
select t1.*,t2.* from t1 left join t2 using (c);
|
select t1.*,t2.* from t1 left join t2 using (c);
|
||||||
select t1.*,t2.* from t1 natural left outer join t2;
|
select t1.*,t2.* from t1 natural left outer join t2;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#!@PERL@
|
#!@PERL@ -w
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
@ -36,8 +36,9 @@ WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome.
|
|||||||
|
|
||||||
# Documentation continued at end of file
|
# Documentation continued at end of file
|
||||||
|
|
||||||
my $VERSION = "1.9";
|
my $VERSION = "1.10";
|
||||||
my $opt_tmpdir= $main::ENV{TMPDIR};
|
|
||||||
|
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
|
||||||
|
|
||||||
my $OPTIONS = <<"_OPTIONS";
|
my $OPTIONS = <<"_OPTIONS";
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ sub usage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my %opt = (
|
my %opt = (
|
||||||
user => getpwuid($>),
|
user => scalar getpwuid($>),
|
||||||
noindices => 0,
|
noindices => 0,
|
||||||
allowold => 0, # for safety
|
allowold => 0, # for safety
|
||||||
keepold => 0,
|
keepold => 0,
|
||||||
@ -139,7 +140,7 @@ else {
|
|||||||
|
|
||||||
my %mysqld_vars;
|
my %mysqld_vars;
|
||||||
my $start_time = time;
|
my $start_time = time;
|
||||||
my $opt_tmpdir= $opt{tmpdir} ? $opt{tmpdir} : $main::ENV{TMPDIR};
|
$opt_tmpdir= $opt{tmpdir} if $opt{tmpdir};
|
||||||
$0 = $1 if $0 =~ m:/([^/]+)$:;
|
$0 = $1 if $0 =~ m:/([^/]+)$:;
|
||||||
$opt{quiet} = 0 if $opt{debug};
|
$opt{quiet} = 0 if $opt{debug};
|
||||||
$opt{allowold} = 1 if $opt{keepold};
|
$opt{allowold} = 1 if $opt{keepold};
|
||||||
@ -235,16 +236,17 @@ foreach my $rdb ( @db_desc ) {
|
|||||||
or die "Cannot open dir '$db_dir': $!";
|
or die "Cannot open dir '$db_dir': $!";
|
||||||
|
|
||||||
my %db_files;
|
my %db_files;
|
||||||
map { ( /(.+)\.\w+$/ ? { $db_files{$_} = $1 } : () ) } readdir(DBDIR);
|
map { ( /(.+)\.\w+$/ ? ( $db_files{$_} = $1 ) : () ) } readdir(DBDIR);
|
||||||
unless( keys %db_files ) {
|
unless( keys %db_files ) {
|
||||||
warn "'$db' is an empty database\n";
|
warn "'$db' is an empty database\n";
|
||||||
}
|
}
|
||||||
closedir( DBDIR );
|
closedir( DBDIR );
|
||||||
|
|
||||||
## filter (out) files specified in t_regex
|
## filter (out) files specified in t_regex
|
||||||
my @db_files = sort ( $negated
|
my @db_files = ( $negated
|
||||||
? grep { $db_files{$_} !~ $t_regex } keys %db_files
|
? grep { $db_files{$_} !~ $t_regex } keys %db_files
|
||||||
: grep { $db_files{$_} =~ $t_regex } keys %db_files );
|
: grep { $db_files{$_} =~ $t_regex } keys %db_files );
|
||||||
|
@db_files = sort @db_files;
|
||||||
my @index_files=();
|
my @index_files=();
|
||||||
|
|
||||||
## remove indices unless we're told to keep them
|
## remove indices unless we're told to keep them
|
||||||
@ -776,3 +778,5 @@ Scott Wiersdorf - added table regex and scp support
|
|||||||
|
|
||||||
Monty - working --noindex (copy only first 2048 bytes of index file)
|
Monty - working --noindex (copy only first 2048 bytes of index file)
|
||||||
Fixes for --method=scp
|
Fixes for --method=scp
|
||||||
|
|
||||||
|
Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again.
|
||||||
|
@ -78,7 +78,7 @@ const char *ha_berkeley_ext=".db";
|
|||||||
bool berkeley_skip=0,berkeley_shared_data=0;
|
bool berkeley_skip=0,berkeley_shared_data=0;
|
||||||
u_int32_t berkeley_init_flags= DB_PRIVATE | DB_RECOVER, berkeley_env_flags=0,
|
u_int32_t berkeley_init_flags= DB_PRIVATE | DB_RECOVER, berkeley_env_flags=0,
|
||||||
berkeley_lock_type=DB_LOCK_DEFAULT;
|
berkeley_lock_type=DB_LOCK_DEFAULT;
|
||||||
ulong berkeley_cache_size;
|
ulong berkeley_cache_size, berkeley_log_buffer_size, berkeley_log_file_size=0;
|
||||||
char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
|
char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
|
||||||
long berkeley_lock_scan_time=0;
|
long berkeley_lock_scan_time=0;
|
||||||
ulong berkeley_trans_retry=1;
|
ulong berkeley_trans_retry=1;
|
||||||
@ -99,7 +99,8 @@ static void berkeley_print_error(const char *db_errpfx, char *buffer);
|
|||||||
static byte* bdb_get_key(BDB_SHARE *share,uint *length,
|
static byte* bdb_get_key(BDB_SHARE *share,uint *length,
|
||||||
my_bool not_used __attribute__((unused)));
|
my_bool not_used __attribute__((unused)));
|
||||||
static BDB_SHARE *get_share(const char *table_name, TABLE *table);
|
static BDB_SHARE *get_share(const char *table_name, TABLE *table);
|
||||||
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key);
|
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key,
|
||||||
|
bool mutex_is_locked);
|
||||||
static int write_status(DB *status_block, char *buff, uint length);
|
static int write_status(DB *status_block, char *buff, uint length);
|
||||||
static void update_status(BDB_SHARE *share, TABLE *table);
|
static void update_status(BDB_SHARE *share, TABLE *table);
|
||||||
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
|
static void berkeley_noticecall(DB_ENV *db_env, db_notices notice);
|
||||||
@ -118,6 +119,23 @@ bool berkeley_init(void)
|
|||||||
berkeley_tmpdir=mysql_tmpdir;
|
berkeley_tmpdir=mysql_tmpdir;
|
||||||
if (!berkeley_home)
|
if (!berkeley_home)
|
||||||
berkeley_home=mysql_real_data_home;
|
berkeley_home=mysql_real_data_home;
|
||||||
|
/*
|
||||||
|
If we don't set set_lg_bsize() we will get into trouble when
|
||||||
|
trying to use many open BDB tables.
|
||||||
|
If log buffer is not set, assume that the we will need 512 byte per
|
||||||
|
open table. This is a number that we have reached by testing.
|
||||||
|
*/
|
||||||
|
if (!berkeley_log_buffer_size)
|
||||||
|
{
|
||||||
|
berkeley_log_buffer_size= max(table_cache_size*512,32*1024);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Berkeley DB require that
|
||||||
|
berkeley_log_file_size >= berkeley_log_buffer_size*4
|
||||||
|
*/
|
||||||
|
berkeley_log_file_size= berkeley_log_buffer_size*4;
|
||||||
|
berkeley_log_file_size= MY_ALIGN(berkeley_log_file_size,1024*1024L);
|
||||||
|
berkeley_log_file_size= max(berkeley_log_file_size, 10*1024*1024L);
|
||||||
|
|
||||||
if (db_env_create(&db_env,0))
|
if (db_env_create(&db_env,0))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
@ -136,6 +154,8 @@ bool berkeley_init(void)
|
|||||||
1);
|
1);
|
||||||
|
|
||||||
db_env->set_cachesize(db_env, 0, berkeley_cache_size, 0);
|
db_env->set_cachesize(db_env, 0, berkeley_cache_size, 0);
|
||||||
|
db_env->set_lg_max(db_env, berkeley_log_file_size);
|
||||||
|
db_env->set_lg_bsize(db_env, berkeley_log_buffer_size);
|
||||||
db_env->set_lk_detect(db_env, berkeley_lock_type);
|
db_env->set_lk_detect(db_env, berkeley_lock_type);
|
||||||
if (berkeley_max_lock)
|
if (berkeley_max_lock)
|
||||||
db_env->set_lk_max(db_env, berkeley_max_lock);
|
db_env->set_lk_max(db_env, berkeley_max_lock);
|
||||||
@ -465,7 +485,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
|
|||||||
{
|
{
|
||||||
if ((error=db_create(&file, db_env, 0)))
|
if ((error=db_create(&file, db_env, 0)))
|
||||||
{
|
{
|
||||||
free_share(share,table, hidden_primary_key);
|
free_share(share,table, hidden_primary_key,1);
|
||||||
my_free(rec_buff,MYF(0));
|
my_free(rec_buff,MYF(0));
|
||||||
my_free(alloc_ptr,MYF(0));
|
my_free(alloc_ptr,MYF(0));
|
||||||
my_errno=error;
|
my_errno=error;
|
||||||
@ -482,7 +502,7 @@ int ha_berkeley::open(const char *name, int mode, uint test_if_locked)
|
|||||||
2 | 4),
|
2 | 4),
|
||||||
"main", DB_BTREE, open_mode,0))))
|
"main", DB_BTREE, open_mode,0))))
|
||||||
{
|
{
|
||||||
free_share(share,table, hidden_primary_key);
|
free_share(share,table, hidden_primary_key,1);
|
||||||
my_free(rec_buff,MYF(0));
|
my_free(rec_buff,MYF(0));
|
||||||
my_free(alloc_ptr,MYF(0));
|
my_free(alloc_ptr,MYF(0));
|
||||||
my_errno=error;
|
my_errno=error;
|
||||||
@ -555,7 +575,7 @@ int ha_berkeley::close(void)
|
|||||||
|
|
||||||
my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(rec_buff,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(alloc_ptr,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
DBUG_RETURN(free_share(share,table, hidden_primary_key));
|
DBUG_RETURN(free_share(share,table, hidden_primary_key,0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2077,11 +2097,14 @@ static BDB_SHARE *get_share(const char *table_name, TABLE *table)
|
|||||||
return share;
|
return share;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key)
|
static int free_share(BDB_SHARE *share, TABLE *table, uint hidden_primary_key,
|
||||||
|
bool mutex_is_locked)
|
||||||
{
|
{
|
||||||
int error, result = 0;
|
int error, result = 0;
|
||||||
uint keys=table->keys + test(hidden_primary_key);
|
uint keys=table->keys + test(hidden_primary_key);
|
||||||
pthread_mutex_lock(&bdb_mutex);
|
pthread_mutex_lock(&bdb_mutex);
|
||||||
|
if (mutex_is_locked)
|
||||||
|
pthread_mutex_unlock(&share->mutex);
|
||||||
if (!--share->use_count)
|
if (!--share->use_count)
|
||||||
{
|
{
|
||||||
DB **key_file = share->key_file;
|
DB **key_file = share->key_file;
|
||||||
|
@ -168,7 +168,7 @@ class ha_berkeley: public handler
|
|||||||
extern bool berkeley_skip, berkeley_shared_data;
|
extern bool berkeley_skip, berkeley_shared_data;
|
||||||
extern u_int32_t berkeley_init_flags,berkeley_env_flags, berkeley_lock_type,
|
extern u_int32_t berkeley_init_flags,berkeley_env_flags, berkeley_lock_type,
|
||||||
berkeley_lock_types[];
|
berkeley_lock_types[];
|
||||||
extern ulong berkeley_cache_size, berkeley_max_lock;
|
extern ulong berkeley_cache_size, berkeley_max_lock, berkeley_log_buffer_size;
|
||||||
extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
|
extern char *berkeley_home, *berkeley_tmpdir, *berkeley_logdir;
|
||||||
extern long berkeley_lock_scan_time;
|
extern long berkeley_lock_scan_time;
|
||||||
extern TYPELIB berkeley_lock_typelib;
|
extern TYPELIB berkeley_lock_typelib;
|
||||||
|
@ -22,102 +22,27 @@ Innobase */
|
|||||||
|
|
||||||
/* TODO list for the Innobase handler:
|
/* TODO list for the Innobase handler:
|
||||||
- How to check for deadlocks if Innobase tables are used alongside
|
- How to check for deadlocks if Innobase tables are used alongside
|
||||||
other MySQL table types? Should MySQL communicate the locking
|
other MySQL table types? Solution: we will use a timeout.
|
||||||
information also to Innobase of any object it locks, or should
|
|
||||||
we use a timeout to detect a deadlock? Solution: there is no problem,
|
|
||||||
because MySQL requires that all table-level locks are reserved
|
|
||||||
at transaction startup (conservative locking). Deadlocks cannot
|
|
||||||
occur because of these locks.
|
|
||||||
- Innobase cmp function should call MySQL cmp for most datatypes?
|
|
||||||
Except currently for binary strings and 32-bit integers?
|
|
||||||
Solution: MySQL has conversion functions which currently convert
|
|
||||||
any datatype to a binary string which can be compared as binary
|
|
||||||
strings, except for character strings where we must identify
|
|
||||||
lower case with upper case.
|
|
||||||
- MySQL parser should know SELECT FOR UPDATE and SELECT WITH SHARED LOCKS
|
- MySQL parser should know SELECT FOR UPDATE and SELECT WITH SHARED LOCKS
|
||||||
for Innobase interface. We probably will make the non-locking
|
for Innobase interface. We probably will make the non-locking
|
||||||
consistent read the default in Innobase like in Oracle.
|
consistent read the default in Innobase like in Oracle.
|
||||||
- Does function next_same require matching of the whole last field,
|
|
||||||
or it is enough that the common prefix of the last field matches?
|
|
||||||
Answer: it is enough that the common prefix matches.
|
|
||||||
- Is the 'ref' field in handle pre-allocated to be big enough? Primary key
|
|
||||||
values can be very long! Answer: we can reallocate it to be long enough.
|
|
||||||
- DELETE FROM TABLE must not drop the table like it does now, because
|
|
||||||
consistent read will not work then! Answer: there is probably a flag
|
|
||||||
in MySQL which we can use to prevent dropping of a table in this case.
|
|
||||||
-------Oct 24, 2000
|
|
||||||
- Update trx pointers in 'prebuilt' when the transaction object of
|
|
||||||
the handle changes. Answer: in 'external_lock' we always set the pointers
|
|
||||||
to point to the trx of the current user. Note that if a user has
|
|
||||||
disconnected, then another thd at exactly the same machine address may
|
|
||||||
be created: just comparing the thd pointers does not really tell if it
|
|
||||||
actually is the same user using the handle!
|
|
||||||
- ANSI SQL specifies that if an SQL statement fails because of
|
|
||||||
an error (like duplicate key, division by zero), the whole statement
|
|
||||||
must be rolled back. Currently an error like this only rolls
|
|
||||||
back a single insert of a row, or a single row update.
|
|
||||||
-------Oct 25, 2000
|
|
||||||
- There are some autonomous threads within Innobase, like purge (= gc),
|
|
||||||
ibuf merge, and recovery threads, which may have to open tables.
|
|
||||||
Then they need type information for the table columns from MySQL.
|
|
||||||
Could they call 'openfrm' in MySQL? Then they should be properly
|
|
||||||
initialized pthreads, I presume.
|
|
||||||
-------Oct 30, 2000
|
|
||||||
- Dropping of table in Innobase fails if there is a lock set on it:
|
- Dropping of table in Innobase fails if there is a lock set on it:
|
||||||
Innobase then gives an error number to MySQL but MySQL seems to drop
|
Innobase then gives an error number to MySQL but MySQL seems to drop
|
||||||
the table from its own data dictionary anyway, causing incoherence
|
the table from its own data dictionary anyway, causing incoherence
|
||||||
between the two databases.
|
between the two databases. Solution: sleep until locks have been
|
||||||
-------Oct 31, 2000
|
released.
|
||||||
- In sql_table.cpp in quick_rm_table, the path has to be 'unpacked'
|
|
||||||
also after the latter sprintf to change / to \ in the path name.
|
|
||||||
- Innobase currently includes the path to a table name: the path should
|
- Innobase currently includes the path to a table name: the path should
|
||||||
actually be dropped off, because we may move a whole database to a new
|
actually be dropped off, because we may move a whole database to a new
|
||||||
directory.
|
directory.
|
||||||
-------Nov 1, 2000
|
|
||||||
- Ask from Monty what error codes 'record not found' and 'end of table'
|
|
||||||
exactly mean and when read and fetch operations should return them.
|
|
||||||
-------Nov 2, 2000
|
|
||||||
- Find out why in 'test-ATIS' in 'bench' directory, the client does
|
|
||||||
not seem to receive rows sent by the server: maybe Innobase does not
|
|
||||||
handle 'decimal' type correctly. Answer: Innobase did not return
|
|
||||||
'record not found' and 'end of table' with right meanings.
|
|
||||||
-------Nov 3, 2000
|
|
||||||
- 'pack' adds field length in front of string type fields: fields of
|
|
||||||
different length are not correctly alphabetically ordered.
|
|
||||||
- 'pack' removes leading (or was it, trailing) spaces from string type
|
|
||||||
fields: maybe it would be better to store them as they are, if the
|
|
||||||
field is not declared as varchar.
|
|
||||||
- MySQL 'read_last_with_key' does not allow Innobase to return
|
|
||||||
HA_ERR_KEY_NOT_FOUND, even when we try to read from an empty
|
|
||||||
table.
|
|
||||||
-------Nov 4, 2000
|
|
||||||
- MySQL should know when row id is added as uniquefier to a table for
|
|
||||||
update and delete to work.
|
|
||||||
- Innobase does not really support MySQL varchar type yet.
|
|
||||||
-------Nov 16, 2000
|
|
||||||
- We use memcpy to store float and double types to Innobase: this
|
- We use memcpy to store float and double types to Innobase: this
|
||||||
makes database files not portable between big-endian and little-endian
|
makes database files not portable between big-endian and little-endian
|
||||||
machines.
|
machines.
|
||||||
-------Nov 17, 2000
|
|
||||||
- We added call of innobase_close_connection to THD::~THD in sql_class.cpp.
|
|
||||||
-------Nov 21, 2000
|
|
||||||
- In mysql_delete, in sql_delete.cpp, we must be able to prevent
|
- In mysql_delete, in sql_delete.cpp, we must be able to prevent
|
||||||
MySQL from using generate_table to do a delete: consistent read does
|
MySQL from using generate_table to do a delete: consistent read does
|
||||||
not allow this. Currently, MySQL uses generate_table in DELETE FROM ...
|
not allow this. Currently, MySQL uses generate_table in DELETE FROM ...
|
||||||
if autocommit is on.
|
if autocommit is on.
|
||||||
-------Nov 24, 2000
|
|
||||||
- Make the SELECT in an update a locking read.
|
- Make the SELECT in an update a locking read.
|
||||||
- Add a deadlock error message to MySQL.
|
- Add a deadlock error message to MySQL.
|
||||||
- Add 'cannot drop locked table' error message to MySQL.
|
|
||||||
-------Nov 26, 2000
|
|
||||||
- Find out why MySQL sometimes prints error message about read locks and
|
|
||||||
write locks associated with a handle.
|
|
||||||
- Find out why MySQL at shutdown prints error message 'Error on delete of
|
|
||||||
......pid (Errcode : 2).
|
|
||||||
-------Nov 30, 2000
|
|
||||||
- MySQL calls innobase_end (shutdown) before it knows that all handles
|
|
||||||
have been closed. It declares MySQL shutdown complete before Innobase
|
|
||||||
shutdown is complete.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
@ -131,43 +56,50 @@ Innobase */
|
|||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <myisampack.h>
|
#include <myisampack.h>
|
||||||
|
|
||||||
|
#include "ha_innobase.h"
|
||||||
|
|
||||||
|
/* We use the following define in univ.i to remove a conflicting definition
|
||||||
|
of type 'byte' in univ.i, different from MySQL definition */
|
||||||
|
#define INSIDE_HA_INNOBASE_CC
|
||||||
|
|
||||||
|
/* NOTE! When we include univ.i below, bool will be defined in the Innobase
|
||||||
|
way as an unsigned long int! In MySQL source code bool may be char. */
|
||||||
|
|
||||||
/* Include necessary Innobase headers */
|
/* Include necessary Innobase headers */
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <univmysql.i>
|
#include "../innobase/include/univ.i"
|
||||||
#include <srv0start.h>
|
#include "../innobase/include/srv0start.h"
|
||||||
#include <srv0srv.h>
|
#include "../innobase/include/srv0srv.h"
|
||||||
#include <trx0roll.h>
|
#include "../innobase/include/trx0roll.h"
|
||||||
#include <trx0trx.h>
|
#include "../innobase/include/trx0trx.h"
|
||||||
#include <row0ins.h>
|
#include "../innobase/include/row0ins.h"
|
||||||
#include <row0mysql.h>
|
#include "../innobase/include/row0mysql.h"
|
||||||
#include <row0sel.h>
|
#include "../innobase/include/row0sel.h"
|
||||||
#include <row0upd.h>
|
#include "../innobase/include/row0upd.h"
|
||||||
#include <log0log.h>
|
#include "../innobase/include/log0log.h"
|
||||||
#include <dict0crea.h>
|
#include "../innobase/include/dict0crea.h"
|
||||||
#include <btr0cur.h>
|
#include "../innobase/include/btr0cur.h"
|
||||||
#include <btr0btr.h>
|
#include "../innobase/include/btr0btr.h"
|
||||||
}
|
}
|
||||||
#include "ha_innobase.h"
|
|
||||||
|
|
||||||
|
|
||||||
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
|
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
|
||||||
#define HA_INNOBASE_RANGE_COUNT 100
|
#define HA_INNOBASE_RANGE_COUNT 100
|
||||||
|
|
||||||
const char* ha_innobase_ext = ".ib";
|
const char* ha_innobase_ext = ".ib";
|
||||||
|
|
||||||
bool innobase_skip = 0;
|
mysql_bool innobase_skip = 0;
|
||||||
uint innobase_init_flags = 0;
|
uint innobase_init_flags = 0;
|
||||||
ulong innobase_cache_size = 0;
|
ulong innobase_cache_size = 0;
|
||||||
|
|
||||||
long innobase_mirrored_log_groups, innobase_mirrored_log_groups,
|
long innobase_mirrored_log_groups, innobase_log_files_in_group,
|
||||||
innobase_log_file_size, innobase_log_buffer_size,
|
innobase_log_file_size, innobase_log_buffer_size,
|
||||||
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
|
innobase_buffer_pool_size, innobase_additional_mem_pool_size,
|
||||||
innobase_file_io_threads;
|
innobase_file_io_threads;
|
||||||
|
|
||||||
char *innobase_data_home_dir, *innobase_data_file_path;
|
char *innobase_data_home_dir, *innobase_data_file_path;
|
||||||
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||||
bool innobase_flush_log_at_trx_commit,innobase_log_archive;
|
mysql_bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||||
|
innobase_use_native_aio;
|
||||||
|
|
||||||
/* innobase_data_file_path=ibdata:15,idata2:1,... */
|
/* innobase_data_file_path=ibdata:15,idata2:1,... */
|
||||||
|
|
||||||
@ -182,9 +114,9 @@ ulong innobase_select_counter = 0;
|
|||||||
|
|
||||||
char* innobase_home = NULL;
|
char* innobase_home = NULL;
|
||||||
|
|
||||||
pthread_mutex_t innb_mutex;
|
pthread_mutex_t innobase_mutex;
|
||||||
|
|
||||||
static HASH innb_open_tables;
|
static HASH innobase_open_tables;
|
||||||
|
|
||||||
static byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
|
static byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
|
||||||
my_bool not_used __attribute__((unused)));
|
my_bool not_used __attribute__((unused)));
|
||||||
@ -261,12 +193,20 @@ check_trx_exists(
|
|||||||
|
|
||||||
assert(thd != NULL);
|
assert(thd != NULL);
|
||||||
|
|
||||||
trx = (trx_t*) thd->transaction.innobase_trx_handle;
|
trx = (trx_t*) thd->transaction.all.innobase_tid;
|
||||||
|
|
||||||
if (trx == NULL) {
|
if (trx == NULL) {
|
||||||
trx = trx_allocate_for_mysql();
|
trx = trx_allocate_for_mysql();
|
||||||
|
|
||||||
thd->transaction.innobase_trx_handle = trx;
|
thd->transaction.all.innobase_tid = trx;
|
||||||
|
|
||||||
|
/* The execution of a single SQL statement is denoted by
|
||||||
|
a 'transaction' handle which is a NULL pointer: Innobase
|
||||||
|
remembers internally where the latest SQL statement
|
||||||
|
started, and if error handling requires rolling back the
|
||||||
|
latest statement, Innobase does a rollback to a savepoint. */
|
||||||
|
|
||||||
|
thd->transaction.stmt.innobase_tid = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(trx);
|
return(trx);
|
||||||
@ -298,25 +238,226 @@ ha_innobase::update_thd(
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Reads the data files and their sizes from a character string given in
|
||||||
|
the .cnf file. */
|
||||||
|
static
|
||||||
|
mysql_bool
|
||||||
|
innobase_parse_data_file_paths_and_sizes(void)
|
||||||
|
/*==========================================*/
|
||||||
|
/* out: ((mysql_bool)TRUE) if ok,
|
||||||
|
((mysql_bool)FALSE) if parsing
|
||||||
|
error */
|
||||||
|
{
|
||||||
|
char* str;
|
||||||
|
char* endp;
|
||||||
|
char* path;
|
||||||
|
ulint size;
|
||||||
|
ulint i = 0;
|
||||||
|
|
||||||
|
str = innobase_data_file_path;
|
||||||
|
|
||||||
|
/* First calculate the number of data files and check syntax:
|
||||||
|
path:size[M];path:size[M]... */
|
||||||
|
|
||||||
|
while (*str != '\0') {
|
||||||
|
path = str;
|
||||||
|
|
||||||
|
while (*str != ':' && *str != '\0') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*str == '\0') {
|
||||||
|
return(((mysql_bool)FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
str++;
|
||||||
|
|
||||||
|
size = strtoul(str, &endp, 10);
|
||||||
|
|
||||||
|
str = endp;
|
||||||
|
if (*str != 'M') {
|
||||||
|
size = size / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0) {
|
||||||
|
return(((mysql_bool)FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (*str == ';') {
|
||||||
|
str++;
|
||||||
|
} else if (*str != '\0') {
|
||||||
|
|
||||||
|
return(((mysql_bool)FALSE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_data_file_names = (char**) ut_malloc(i * sizeof(void*));
|
||||||
|
srv_data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint));
|
||||||
|
|
||||||
|
srv_n_data_files = i;
|
||||||
|
|
||||||
|
/* Then store the actual values to our arrays */
|
||||||
|
|
||||||
|
str = innobase_data_file_path;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (*str != '\0') {
|
||||||
|
path = str;
|
||||||
|
|
||||||
|
while (*str != ':' && *str != '\0') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*str == ':') {
|
||||||
|
/* Make path a null-terminated string */
|
||||||
|
*str = '\0';
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
size = strtoul(str, &endp, 10);
|
||||||
|
|
||||||
|
str = endp;
|
||||||
|
if (*str != 'M') {
|
||||||
|
size = size / (1024 * 1024);
|
||||||
|
} else {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_data_file_names[i] = path;
|
||||||
|
srv_data_file_sizes[i] = size;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (*str == ';') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(((mysql_bool)TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
Reads log group home directories from a character string given in
|
||||||
|
the .cnf file. */
|
||||||
|
static
|
||||||
|
mysql_bool
|
||||||
|
innobase_parse_log_group_home_dirs(void)
|
||||||
|
/*====================================*/
|
||||||
|
/* out: ((mysql_bool)TRUE) if ok,
|
||||||
|
((mysql_bool)FALSE) if parsing
|
||||||
|
error */
|
||||||
|
{
|
||||||
|
char* str;
|
||||||
|
char* path;
|
||||||
|
ulint i = 0;
|
||||||
|
|
||||||
|
str = innobase_log_group_home_dir;
|
||||||
|
|
||||||
|
/* First calculate the number of directories and check syntax:
|
||||||
|
path;path;... */
|
||||||
|
|
||||||
|
while (*str != '\0') {
|
||||||
|
path = str;
|
||||||
|
|
||||||
|
while (*str != ';' && *str != '\0') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (*str == ';') {
|
||||||
|
str++;
|
||||||
|
} else if (*str != '\0') {
|
||||||
|
|
||||||
|
return(((mysql_bool)FALSE));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i != (ulint) innobase_mirrored_log_groups) {
|
||||||
|
|
||||||
|
return(((mysql_bool)FALSE));
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_log_group_home_dirs = (char**) ut_malloc(i * sizeof(void*));
|
||||||
|
|
||||||
|
/* Then store the actual values to our array */
|
||||||
|
|
||||||
|
str = innobase_log_group_home_dir;
|
||||||
|
i = 0;
|
||||||
|
|
||||||
|
while (*str != '\0') {
|
||||||
|
path = str;
|
||||||
|
|
||||||
|
while (*str != ';' && *str != '\0') {
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*str == ';') {
|
||||||
|
*str = '\0';
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_log_group_home_dirs[i] = path;
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(((mysql_bool)TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Opens an Innobase database. */
|
Opens an Innobase database. */
|
||||||
|
|
||||||
bool
|
mysql_bool
|
||||||
innobase_init(void)
|
innobase_init(void)
|
||||||
/*===============*/
|
/*===============*/
|
||||||
/* out: TRUE if error */
|
/* out: ((mysql_bool)TRUE) if error */
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
mysql_bool ret;
|
||||||
|
|
||||||
DBUG_ENTER("innobase_init");
|
DBUG_ENTER("innobase_init");
|
||||||
|
|
||||||
if (!innobase_home) {
|
/* Set Innobase initialization parameters according to the values
|
||||||
innobase_home = mysql_real_data_home;
|
read from MySQL .cnf file */
|
||||||
|
|
||||||
printf("Innobase home is %s\n", innobase_home);
|
srv_data_home = innobase_data_home_dir;
|
||||||
}
|
srv_logs_home = "";
|
||||||
|
srv_arch_dir = innobase_log_arch_dir;
|
||||||
|
|
||||||
err = innobase_start_or_create_for_mysql(innobase_home);
|
ret = innobase_parse_data_file_paths_and_sizes();
|
||||||
|
|
||||||
|
if (ret == ((mysql_bool)FALSE)) {
|
||||||
|
return(((mysql_bool)TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = innobase_parse_log_group_home_dirs();
|
||||||
|
|
||||||
|
if (ret == ((mysql_bool)FALSE)) {
|
||||||
|
return(((mysql_bool)TRUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
|
||||||
|
srv_n_log_files = (ulint) innobase_log_files_in_group;
|
||||||
|
srv_log_file_size = (ulint) innobase_log_file_size;
|
||||||
|
|
||||||
|
srv_log_archive_on = (ulint) innobase_log_archive;
|
||||||
|
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
|
||||||
|
srv_flush_log_at_trx_commit = (ulint) innobase_flush_log_at_trx_commit;
|
||||||
|
|
||||||
|
srv_use_native_aio = (ulint) innobase_use_native_aio;
|
||||||
|
|
||||||
|
srv_pool_size = (ulint) innobase_buffer_pool_size;
|
||||||
|
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
|
||||||
|
|
||||||
|
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
|
||||||
|
|
||||||
|
err = innobase_start_or_create_for_mysql();
|
||||||
|
|
||||||
if (err != DB_SUCCESS) {
|
if (err != DB_SUCCESS) {
|
||||||
|
|
||||||
@ -331,10 +472,10 @@ innobase_init(void)
|
|||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
Closes an Innobase database. */
|
Closes an Innobase database. */
|
||||||
|
|
||||||
bool
|
mysql_bool
|
||||||
innobase_end(void)
|
innobase_end(void)
|
||||||
/*==============*/
|
/*==============*/
|
||||||
/* out: TRUE if error */
|
/* out: ((mysql_bool)TRUE) if error */
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
@ -354,12 +495,12 @@ innobase_end(void)
|
|||||||
Flushes Innobase logs to disk and makes a checkpoint. Really, a commit
|
Flushes Innobase logs to disk and makes a checkpoint. Really, a commit
|
||||||
flushes logs, and the name of this function should be innobase_checkpoint. */
|
flushes logs, and the name of this function should be innobase_checkpoint. */
|
||||||
|
|
||||||
bool
|
mysql_bool
|
||||||
innobase_flush_logs(void)
|
innobase_flush_logs(void)
|
||||||
/*=====================*/
|
/*=====================*/
|
||||||
/* out: TRUE if error */
|
/* out: ((mysql_bool)TRUE) if error */
|
||||||
{
|
{
|
||||||
bool result = 0;
|
mysql_bool result = 0;
|
||||||
|
|
||||||
DBUG_ENTER("innobase_flush_logs");
|
DBUG_ENTER("innobase_flush_logs");
|
||||||
|
|
||||||
@ -375,8 +516,11 @@ int
|
|||||||
innobase_commit(
|
innobase_commit(
|
||||||
/*============*/
|
/*============*/
|
||||||
/* out: 0 or error number */
|
/* out: 0 or error number */
|
||||||
THD* thd) /* in: MySQL thread handle of the user for whom
|
THD* thd, /* in: MySQL thread handle of the user for whom
|
||||||
the transaction should be committed */
|
the transaction should be committed */
|
||||||
|
void* trx_handle)/* in: Innobase trx handle or NULL: NULL means
|
||||||
|
that the current SQL statement ended, and we should
|
||||||
|
mark the start of a new statement with a savepoint */
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
@ -385,7 +529,13 @@ innobase_commit(
|
|||||||
|
|
||||||
check_trx_exists(thd);
|
check_trx_exists(thd);
|
||||||
|
|
||||||
trx_commit_for_mysql((trx_t*)(thd->transaction.innobase_trx_handle));
|
if (trx_handle) {
|
||||||
|
trx_commit_for_mysql(
|
||||||
|
(trx_t*) (thd->transaction.all.innobase_tid));
|
||||||
|
} else {
|
||||||
|
trx_mark_sql_stat_end(
|
||||||
|
(trx_t*) (thd->transaction.all.innobase_tid));
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -407,8 +557,11 @@ int
|
|||||||
innobase_rollback(
|
innobase_rollback(
|
||||||
/*==============*/
|
/*==============*/
|
||||||
/* out: 0 or error number */
|
/* out: 0 or error number */
|
||||||
THD* thd) /* in: handle to the MySQL thread of the user
|
THD* thd, /* in: handle to the MySQL thread of the user
|
||||||
whose transaction should be rolled back */
|
whose transaction should be rolled back */
|
||||||
|
void* trx_handle)/* in: Innobase trx handle or NULL: NULL means
|
||||||
|
that the current SQL statement should be rolled
|
||||||
|
back */
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
@ -417,8 +570,13 @@ innobase_rollback(
|
|||||||
|
|
||||||
check_trx_exists(thd);
|
check_trx_exists(thd);
|
||||||
|
|
||||||
error = trx_rollback_for_mysql((trx_t*)
|
if (trx_handle) {
|
||||||
(thd->transaction.innobase_trx_handle));
|
error = trx_rollback_for_mysql(
|
||||||
|
(trx_t*) (thd->transaction.all.innobase_tid));
|
||||||
|
} else {
|
||||||
|
error = trx_rollback_last_sql_stat_for_mysql(
|
||||||
|
(trx_t*) (thd->transaction.all.innobase_tid));
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(convert_error_code_to_mysql(error));
|
DBUG_RETURN(convert_error_code_to_mysql(error));
|
||||||
}
|
}
|
||||||
@ -434,10 +592,10 @@ innobase_close_connection(
|
|||||||
THD* thd) /* in: handle to the MySQL thread of the user
|
THD* thd) /* in: handle to the MySQL thread of the user
|
||||||
whose transaction should be rolled back */
|
whose transaction should be rolled back */
|
||||||
{
|
{
|
||||||
if (NULL != thd->transaction.innobase_trx_handle) {
|
if (NULL != thd->transaction.all.innobase_tid) {
|
||||||
|
|
||||||
trx_free_for_mysql((trx_t*)
|
trx_free_for_mysql((trx_t*)
|
||||||
(thd->transaction.innobase_trx_handle));
|
(thd->transaction.all.innobase_tid));
|
||||||
}
|
}
|
||||||
|
|
||||||
return(0);
|
return(0);
|
||||||
@ -482,7 +640,7 @@ ha_innobase::open(
|
|||||||
/* out: 1 if error, 0 if success */
|
/* out: 1 if error, 0 if success */
|
||||||
const char* name, /* in: table name */
|
const char* name, /* in: table name */
|
||||||
int mode, /* in: not used */
|
int mode, /* in: not used */
|
||||||
int test_if_locked) /* in: not used */
|
uint test_if_locked) /* in: not used */
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
uint buff_len;
|
uint buff_len;
|
||||||
@ -1042,12 +1200,14 @@ ha_innobase::store_key_val_for_row(
|
|||||||
/******************************************************************
|
/******************************************************************
|
||||||
Convert a row in MySQL format to a row in Innobase format. Uses rec_buff
|
Convert a row in MySQL format to a row in Innobase format. Uses rec_buff
|
||||||
of the handle. */
|
of the handle. */
|
||||||
|
static
|
||||||
void
|
void
|
||||||
ha_innobase::convert_row_to_innobase(
|
convert_row_to_innobase(
|
||||||
/*=================================*/
|
/*====================*/
|
||||||
dtuple_t* row, /* in/out: row in Innobase format */
|
dtuple_t* row, /* in/out: row in Innobase format */
|
||||||
char* record) /* in: row in MySQL format */
|
char* record, /* in: row in MySQL format */
|
||||||
|
byte* rec_buff,/* in: record buffer */
|
||||||
|
struct st_table* table) /* in: table in MySQL data dictionary */
|
||||||
{
|
{
|
||||||
Field* field;
|
Field* field;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@ -1083,12 +1243,13 @@ ha_innobase::convert_row_to_innobase(
|
|||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
Convert a row in Innobase format to a row in MySQL format. */
|
Convert a row in Innobase format to a row in MySQL format. */
|
||||||
|
static
|
||||||
void
|
void
|
||||||
ha_innobase::convert_row_to_mysql(
|
convert_row_to_mysql(
|
||||||
/*==============================*/
|
/*=================*/
|
||||||
char* record, /* in/out: row in MySQL format */
|
char* record, /* in/out: row in MySQL format */
|
||||||
dtuple_t* row) /* in: row in Innobase format */
|
dtuple_t* row, /* in: row in Innobase format */
|
||||||
|
struct st_table* table) /* in: table in MySQL data dictionary */
|
||||||
{
|
{
|
||||||
Field* field;
|
Field* field;
|
||||||
dfield_t* dfield;
|
dfield_t* dfield;
|
||||||
@ -1124,10 +1285,10 @@ ha_innobase::convert_row_to_mysql(
|
|||||||
Converts a key value stored in MySQL format to an Innobase dtuple.
|
Converts a key value stored in MySQL format to an Innobase dtuple.
|
||||||
The last field of the key value may be just a prefix of a fixed length
|
The last field of the key value may be just a prefix of a fixed length
|
||||||
field: hence the parameter key_len. */
|
field: hence the parameter key_len. */
|
||||||
|
static
|
||||||
dtuple_t*
|
dtuple_t*
|
||||||
ha_innobase::convert_key_to_innobase(
|
convert_key_to_innobase(
|
||||||
/*=================================*/
|
/*====================*/
|
||||||
dtuple_t* tuple, /* in/out: an Innobase dtuple which
|
dtuple_t* tuple, /* in/out: an Innobase dtuple which
|
||||||
must contain enough fields to be
|
must contain enough fields to be
|
||||||
able to store the key value */
|
able to store the key value */
|
||||||
@ -1231,7 +1392,7 @@ ha_innobase::write_row(
|
|||||||
update_auto_increment();
|
update_auto_increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(user_thd->transaction.innobase_trx_handle);
|
assert(user_thd->transaction.all.innobase_tid);
|
||||||
trx = check_trx_exists(user_thd);
|
trx = check_trx_exists(user_thd);
|
||||||
|
|
||||||
/* Convert the MySQL row into an Innobase dtuple format */
|
/* Convert the MySQL row into an Innobase dtuple format */
|
||||||
@ -1240,7 +1401,7 @@ ha_innobase::write_row(
|
|||||||
(row_prebuilt_t*) innobase_prebuilt,
|
(row_prebuilt_t*) innobase_prebuilt,
|
||||||
(dict_table_t*) innobase_table_handle, trx);
|
(dict_table_t*) innobase_table_handle, trx);
|
||||||
|
|
||||||
convert_row_to_innobase(row, (char*) record);
|
convert_row_to_innobase(row, (char*) record, rec_buff, table);
|
||||||
|
|
||||||
error = row_insert_for_mysql((row_prebuilt_t*)innobase_prebuilt, trx);
|
error = row_insert_for_mysql((row_prebuilt_t*)innobase_prebuilt, trx);
|
||||||
|
|
||||||
@ -1257,16 +1418,19 @@ ha_innobase::write_row(
|
|||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
Checks which fields have changed in a row and stores information
|
Checks which fields have changed in a row and stores information
|
||||||
of them to an update vector. */
|
of them to an update vector. */
|
||||||
|
static
|
||||||
int
|
int
|
||||||
ha_innobase::calc_row_difference(
|
calc_row_difference(
|
||||||
/*=============================*/
|
/*================*/
|
||||||
/* out: error number or 0 */
|
/* out: error number or 0 */
|
||||||
upd_t* uvect, /* in/out: update vector */
|
upd_t* uvect, /* in/out: update vector */
|
||||||
byte* old_row, /* in: old row in MySQL format */
|
byte* old_row, /* in: old row in MySQL format */
|
||||||
byte* new_row) /* in: new row in MySQL format */
|
byte* new_row, /* in: new row in MySQL format */
|
||||||
|
struct st_table* table, /* in: table in MySQL data dictionary */
|
||||||
|
byte* upd_buff, /* in: buffer to use */
|
||||||
|
row_prebuilt_t* prebuilt,/* in: Innobase prebuilt struct */
|
||||||
|
void* innobase_table_handle) /* in: Innobase table handle */
|
||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
|
||||||
Field* field;
|
Field* field;
|
||||||
uint n_fields;
|
uint n_fields;
|
||||||
ulint o_len;
|
ulint o_len;
|
||||||
@ -1353,7 +1517,7 @@ ha_innobase::update_row(
|
|||||||
|
|
||||||
DBUG_ENTER("update_row");
|
DBUG_ENTER("update_row");
|
||||||
|
|
||||||
assert(user_thd->transaction.innobase_trx_handle);
|
assert(user_thd->transaction.all.innobase_tid);
|
||||||
trx = check_trx_exists(user_thd);
|
trx = check_trx_exists(user_thd);
|
||||||
|
|
||||||
uvect = row_get_prebuilt_update_vector(
|
uvect = row_get_prebuilt_update_vector(
|
||||||
@ -1363,13 +1527,14 @@ ha_innobase::update_row(
|
|||||||
/* Build old row in the Innobase format (uses rec_buff of the
|
/* Build old row in the Innobase format (uses rec_buff of the
|
||||||
handle) */
|
handle) */
|
||||||
|
|
||||||
convert_row_to_innobase(prebuilt->row_tuple, (char*) old_row);
|
convert_row_to_innobase(prebuilt->row_tuple, (char*) old_row,
|
||||||
|
rec_buff, table);
|
||||||
|
|
||||||
/* Build an update vector from the modified fields in the rows
|
/* Build an update vector from the modified fields in the rows
|
||||||
(uses upd_buff of the handle) */
|
(uses upd_buff of the handle) */
|
||||||
|
|
||||||
calc_row_difference(uvect, (byte*) old_row, new_row);
|
calc_row_difference(uvect, (byte*) old_row, new_row, table, upd_buff,
|
||||||
|
prebuilt, innobase_table_handle);
|
||||||
/* This is not a delete */
|
/* This is not a delete */
|
||||||
prebuilt->upd_node->is_delete = FALSE;
|
prebuilt->upd_node->is_delete = FALSE;
|
||||||
|
|
||||||
@ -1402,7 +1567,7 @@ ha_innobase::delete_row(
|
|||||||
|
|
||||||
DBUG_ENTER("update_row");
|
DBUG_ENTER("update_row");
|
||||||
|
|
||||||
assert(user_thd->transaction.innobase_trx_handle);
|
assert(user_thd->transaction.all.innobase_tid);
|
||||||
trx = check_trx_exists(user_thd);
|
trx = check_trx_exists(user_thd);
|
||||||
|
|
||||||
uvect = row_get_prebuilt_update_vector(
|
uvect = row_get_prebuilt_update_vector(
|
||||||
@ -1412,8 +1577,8 @@ ha_innobase::delete_row(
|
|||||||
/* Build old row in the Innobase format (uses rec_buff of the
|
/* Build old row in the Innobase format (uses rec_buff of the
|
||||||
handle) */
|
handle) */
|
||||||
|
|
||||||
convert_row_to_innobase(prebuilt->row_tuple, (char*) record);
|
convert_row_to_innobase(prebuilt->row_tuple, (char*) record,
|
||||||
|
rec_buff, table);
|
||||||
/* This is a delete */
|
/* This is a delete */
|
||||||
|
|
||||||
prebuilt->upd_node->is_delete = TRUE;
|
prebuilt->upd_node->is_delete = TRUE;
|
||||||
@ -1527,7 +1692,7 @@ ha_innobase::index_read(
|
|||||||
/* TODO: currently we assume all reads perform consistent read! */
|
/* TODO: currently we assume all reads perform consistent read! */
|
||||||
/* prebuilt->consistent_read = TRUE; */
|
/* prebuilt->consistent_read = TRUE; */
|
||||||
|
|
||||||
assert(user_thd->transaction.innobase_trx_handle);
|
assert(user_thd->transaction.all.innobase_tid);
|
||||||
trx = check_trx_exists(user_thd);
|
trx = check_trx_exists(user_thd);
|
||||||
|
|
||||||
pcur = prebuilt->pcur;
|
pcur = prebuilt->pcur;
|
||||||
@ -1538,7 +1703,7 @@ ha_innobase::index_read(
|
|||||||
|
|
||||||
if (key_ptr) {
|
if (key_ptr) {
|
||||||
convert_key_to_innobase(prebuilt->search_tuple, key_val_buff,
|
convert_key_to_innobase(prebuilt->search_tuple, key_val_buff,
|
||||||
index, key, (unsigned char*) key_ptr,
|
index, key, (byte*) key_ptr,
|
||||||
(int) key_len);
|
(int) key_len);
|
||||||
} else {
|
} else {
|
||||||
/* We position the cursor to the last or the first entry
|
/* We position the cursor to the last or the first entry
|
||||||
@ -1571,7 +1736,7 @@ ha_innobase::index_read(
|
|||||||
trx, &mtr, 0);
|
trx, &mtr, 0);
|
||||||
|
|
||||||
if (ret == DB_SUCCESS) {
|
if (ret == DB_SUCCESS) {
|
||||||
convert_row_to_mysql((char*) buf, prebuilt->row_tuple);
|
convert_row_to_mysql((char*) buf, prebuilt->row_tuple, table);
|
||||||
error = 0;
|
error = 0;
|
||||||
table->status = 0;
|
table->status = 0;
|
||||||
|
|
||||||
@ -1687,7 +1852,7 @@ ha_innobase::general_fetch(
|
|||||||
ret = row_search_for_mysql(prebuilt->row_tuple, 0, prebuilt,
|
ret = row_search_for_mysql(prebuilt->row_tuple, 0, prebuilt,
|
||||||
match_mode, trx, &mtr, direction);
|
match_mode, trx, &mtr, direction);
|
||||||
if (ret == DB_SUCCESS) {
|
if (ret == DB_SUCCESS) {
|
||||||
convert_row_to_mysql((char*) buf, prebuilt->row_tuple);
|
convert_row_to_mysql((char*) buf, prebuilt->row_tuple, table);
|
||||||
error = 0;
|
error = 0;
|
||||||
table->status = 0;
|
table->status = 0;
|
||||||
|
|
||||||
@ -1814,7 +1979,7 @@ int
|
|||||||
ha_innobase::rnd_init(
|
ha_innobase::rnd_init(
|
||||||
/*==================*/
|
/*==================*/
|
||||||
/* out: 0 or error number */
|
/* out: 0 or error number */
|
||||||
bool scan) /* in: ???????? */
|
mysql_bool scan) /* in: ???????? */
|
||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
|
|
||||||
@ -1931,7 +2096,8 @@ ha_innobase::info(
|
|||||||
|
|
||||||
} else if (flag & HA_STATUS_ERRKEY) {
|
} else if (flag & HA_STATUS_ERRKEY) {
|
||||||
|
|
||||||
errkey = -1; /* TODO: get the key number from Innobase */
|
errkey = (unsigned int)-1; /* TODO: get the key number from
|
||||||
|
Innobase */
|
||||||
}
|
}
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
@ -1948,9 +2114,12 @@ int ha_innobase::reset(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
As MySQL will execute an external lock for every new table it uses
|
As MySQL will execute an external lock for every new table it uses when it
|
||||||
we can use this to store the pointer to the THD in the handle. We use this
|
starts to process an SQL statement, we can use this function to store the
|
||||||
also in explicit locking of tables by request of the user. */
|
pointer to the THD in the handle. We will also use this function to communicate
|
||||||
|
to Innobase that a new SQL statement has started and that we must store a
|
||||||
|
savepoint to our transaction handle, so that we are able to roll back
|
||||||
|
the SQL statement in case of an error. */
|
||||||
|
|
||||||
int
|
int
|
||||||
ha_innobase::external_lock(
|
ha_innobase::external_lock(
|
||||||
@ -1958,30 +2127,65 @@ ha_innobase::external_lock(
|
|||||||
THD* thd, /* in: handle to the user thread */
|
THD* thd, /* in: handle to the user thread */
|
||||||
int lock_type) /* in: lock type */
|
int lock_type) /* in: lock type */
|
||||||
{
|
{
|
||||||
int error = 0;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
|
int error = 0;
|
||||||
|
trx_t* trx;
|
||||||
|
|
||||||
DBUG_ENTER("ha_innobase::external_lock");
|
DBUG_ENTER("ha_innobase::external_lock");
|
||||||
|
|
||||||
update_thd(thd);
|
update_thd(thd);
|
||||||
|
|
||||||
|
prebuilt->sql_stat_start = TRUE;
|
||||||
|
|
||||||
|
trx = check_trx_exists(thd);
|
||||||
|
|
||||||
|
if (lock_type != F_UNLCK) {
|
||||||
|
if (trx->n_mysql_tables_in_use == 0) {
|
||||||
|
trx_mark_sql_stat_end(trx);
|
||||||
|
}
|
||||||
|
|
||||||
|
trx->n_mysql_tables_in_use++;
|
||||||
|
} else {
|
||||||
|
trx->n_mysql_tables_in_use--;
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Currently, the following does nothing in Innobase: */
|
/*********************************************************************
|
||||||
THR_LOCK_DATA **ha_innobase::store_lock(THD *thd, THR_LOCK_DATA **to,
|
Stores a MySQL lock into a 'lock' field in a handle. */
|
||||||
enum thr_lock_type lock_type)
|
|
||||||
|
THR_LOCK_DATA**
|
||||||
|
ha_innobase::store_lock(
|
||||||
|
/*====================*/
|
||||||
|
/* out: pointer to the next
|
||||||
|
element in the 'to' array */
|
||||||
|
THD* thd, /* in: user thread handle */
|
||||||
|
THR_LOCK_DATA** to, /* in: pointer to an array
|
||||||
|
of pointers to lock structs;
|
||||||
|
pointer to the 'lock' field
|
||||||
|
of current handle is stored
|
||||||
|
next to this array */
|
||||||
|
enum thr_lock_type lock_type) /* in: lock type to store in
|
||||||
|
'lock' */
|
||||||
{
|
{
|
||||||
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
|
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
|
||||||
{
|
|
||||||
/* If we are not doing a LOCK TABLE, then allow multiple writers */
|
/* If we are not doing a LOCK TABLE, then allow multiple
|
||||||
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
|
writers */
|
||||||
lock_type <= TL_WRITE) &&
|
|
||||||
!thd->in_lock_tables)
|
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
|
||||||
lock_type = TL_WRITE_ALLOW_WRITE;
|
lock_type <= TL_WRITE) && !thd->in_lock_tables) {
|
||||||
lock.type=lock_type;
|
|
||||||
}
|
lock_type = TL_WRITE_ALLOW_WRITE;
|
||||||
*to++= &lock;
|
}
|
||||||
return(to);
|
|
||||||
|
lock.type=lock_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
*to++= &lock;
|
||||||
|
|
||||||
|
return(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
@ -2206,15 +2410,17 @@ ha_innobase::create(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
Drops a table from an Innobase database. No one is allowed to have
|
Drops a table from an Innobase database. Before calling this function,
|
||||||
locks on the table, not even the calling user when the table is
|
MySQL calls innobase_commit to commit the transaction of the current user.
|
||||||
dropped. */
|
Then the current user cannot have locks set on the table. Drop table
|
||||||
|
operation inside Innobase will wait sleeping in a loop until no other
|
||||||
|
user has locks on the table. */
|
||||||
|
|
||||||
int
|
int
|
||||||
ha_innobase::delete_table(
|
ha_innobase::delete_table(
|
||||||
/*======================*/
|
/*======================*/
|
||||||
/* out: error number */
|
/* out: error number */
|
||||||
const char* name) /* in: table name */
|
const char* name) /* in: table name */
|
||||||
{
|
{
|
||||||
ulint name_len;
|
ulint name_len;
|
||||||
int error;
|
int error;
|
||||||
@ -2340,10 +2546,10 @@ ha_innobase::records_in_range(
|
|||||||
byte* key_val_buff2 = (byte*) my_malloc(table->reclength,
|
byte* key_val_buff2 = (byte*) my_malloc(table->reclength,
|
||||||
MYF(MY_WME));
|
MYF(MY_WME));
|
||||||
dtuple_t* range_end;
|
dtuple_t* range_end;
|
||||||
mem_heap_t* heap;
|
|
||||||
ulint n_rows;
|
ulint n_rows;
|
||||||
ulint mode1;
|
ulint mode1;
|
||||||
ulint mode2;
|
ulint mode2;
|
||||||
|
void* heap;
|
||||||
|
|
||||||
DBUG_ENTER("records_in_range");
|
DBUG_ENTER("records_in_range");
|
||||||
|
|
||||||
@ -2363,9 +2569,7 @@ ha_innobase::records_in_range(
|
|||||||
|
|
||||||
/* For the second key value we have to use allocated buffers: */
|
/* For the second key value we have to use allocated buffers: */
|
||||||
|
|
||||||
heap = mem_heap_create(100);
|
range_end = dtuple_create_for_mysql(&heap, key->key_parts);
|
||||||
|
|
||||||
range_end = dtuple_create(heap, key->key_parts);
|
|
||||||
|
|
||||||
convert_key_to_innobase(range_end, key_val_buff2, index,
|
convert_key_to_innobase(range_end, key_val_buff2, index,
|
||||||
key, (byte*) end_key, (int) end_key_len);
|
key, (byte*) end_key, (int) end_key_len);
|
||||||
@ -2375,7 +2579,7 @@ ha_innobase::records_in_range(
|
|||||||
|
|
||||||
n_rows = btr_estimate_n_rows_in_range(index, prebuilt->search_tuple,
|
n_rows = btr_estimate_n_rows_in_range(index, prebuilt->search_tuple,
|
||||||
mode1, range_end, mode2);
|
mode1, range_end, mode2);
|
||||||
mem_heap_free(heap);
|
dtuple_free_for_mysql(heap);
|
||||||
my_free((char*) key_val_buff2, MYF(0));
|
my_free((char*) key_val_buff2, MYF(0));
|
||||||
|
|
||||||
DBUG_RETURN((ha_rows) n_rows);
|
DBUG_RETURN((ha_rows) n_rows);
|
||||||
@ -2398,7 +2602,8 @@ static INNOBASE_SHARE *get_share(const char *table_name)
|
|||||||
INNOBASE_SHARE *share;
|
INNOBASE_SHARE *share;
|
||||||
pthread_mutex_lock(&innobase_mutex);
|
pthread_mutex_lock(&innobase_mutex);
|
||||||
uint length=(uint) strlen(table_name);
|
uint length=(uint) strlen(table_name);
|
||||||
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables, table_name,
|
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
|
||||||
|
(byte*) table_name,
|
||||||
length)))
|
length)))
|
||||||
{
|
{
|
||||||
if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
|
if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
|
||||||
@ -2407,7 +2612,7 @@ static INNOBASE_SHARE *get_share(const char *table_name)
|
|||||||
share->table_name_length=length;
|
share->table_name_length=length;
|
||||||
share->table_name=(char*) (share+1);
|
share->table_name=(char*) (share+1);
|
||||||
strmov(share->table_name,table_name);
|
strmov(share->table_name,table_name);
|
||||||
if (hash_insert(&innobase_open_tables, (char*) share))
|
if (hash_insert(&innobase_open_tables, (byte*) share))
|
||||||
{
|
{
|
||||||
pthread_mutex_unlock(&innobase_mutex);
|
pthread_mutex_unlock(&innobase_mutex);
|
||||||
my_free((gptr) share,0);
|
my_free((gptr) share,0);
|
||||||
@ -2427,7 +2632,7 @@ static void free_share(INNOBASE_SHARE *share)
|
|||||||
pthread_mutex_lock(&innobase_mutex);
|
pthread_mutex_lock(&innobase_mutex);
|
||||||
if (!--share->use_count)
|
if (!--share->use_count)
|
||||||
{
|
{
|
||||||
hash_delete(&innobase_open_tables, (gptr) share);
|
hash_delete(&innobase_open_tables, (byte*) share);
|
||||||
thr_lock_delete(&share->lock);
|
thr_lock_delete(&share->lock);
|
||||||
pthread_mutex_destroy(&share->mutex);
|
pthread_mutex_destroy(&share->mutex);
|
||||||
my_free((gptr) share, MYF(0));
|
my_free((gptr) share, MYF(0));
|
||||||
|
@ -21,15 +21,13 @@
|
|||||||
#pragma interface /* gcc class implementation */
|
#pragma interface /* gcc class implementation */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Store the MySQL bool type definition to this defined type:
|
||||||
|
inside ha_innobase we use the Innobase definition of the bool type! */
|
||||||
|
typedef bool mysql_bool;
|
||||||
|
|
||||||
/* This file defines the Innobase handler: the interface between MySQL and
|
/* This file defines the Innobase handler: the interface between MySQL and
|
||||||
Innobase */
|
Innobase */
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include <data0types.h>
|
|
||||||
#include <dict0types.h>
|
|
||||||
#include <row0types.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct st_innobase_share {
|
typedef struct st_innobase_share {
|
||||||
THR_LOCK lock;
|
THR_LOCK lock;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
@ -73,12 +71,6 @@ class ha_innobase: public handler
|
|||||||
ulong max_row_length(const byte *buf);
|
ulong max_row_length(const byte *buf);
|
||||||
|
|
||||||
uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
|
uint store_key_val_for_row(uint keynr, char* buff, const byte* record);
|
||||||
void convert_row_to_innobase(dtuple_t* row, char* record);
|
|
||||||
void convert_row_to_mysql(char* record, dtuple_t* row);
|
|
||||||
dtuple_t* convert_key_to_innobase(dtuple_t* tuple, byte* buf,
|
|
||||||
dict_index_t* index,
|
|
||||||
KEY* key, byte* key_ptr, int key_len);
|
|
||||||
int calc_row_difference(upd_t* uvect, byte* old_row, byte* new_row);
|
|
||||||
int update_thd(THD* thd);
|
int update_thd(THD* thd);
|
||||||
int change_active_index(uint keynr);
|
int change_active_index(uint keynr);
|
||||||
int general_fetch(byte* buf, uint direction, uint match_mode);
|
int general_fetch(byte* buf, uint direction, uint match_mode);
|
||||||
@ -110,7 +102,7 @@ class ha_innobase: public handler
|
|||||||
bool fast_key_read() { return 1;}
|
bool fast_key_read() { return 1;}
|
||||||
bool has_transactions() { return 1;}
|
bool has_transactions() { return 1;}
|
||||||
|
|
||||||
int open(const char *name, int mode, int test_if_locked);
|
int open(const char *name, int mode, uint test_if_locked);
|
||||||
void initialize(void);
|
void initialize(void);
|
||||||
int close(void);
|
int close(void);
|
||||||
double scan_time();
|
double scan_time();
|
||||||
@ -162,13 +154,14 @@ extern uint innobase_init_flags, innobase_lock_type;
|
|||||||
extern ulong innobase_cache_size;
|
extern ulong innobase_cache_size;
|
||||||
extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
|
extern char *innobase_home, *innobase_tmpdir, *innobase_logdir;
|
||||||
extern long innobase_lock_scan_time;
|
extern long innobase_lock_scan_time;
|
||||||
extern long innobase_mirrored_log_groups, innobase_mirrored_log_groups;
|
extern long innobase_mirrored_log_groups, innobase_log_files_in_group;
|
||||||
extern long innobase_log_file_size, innobase_log_buffer_size;
|
extern long innobase_log_file_size, innobase_log_buffer_size;
|
||||||
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
|
extern long innobase_buffer_pool_size, innobase_additional_mem_pool_size;
|
||||||
extern long innobase_file_io_threads;
|
extern long innobase_file_io_threads;
|
||||||
extern char *innobase_data_home_dir, *innobase_data_file_path;
|
extern char *innobase_data_home_dir, *innobase_data_file_path;
|
||||||
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
extern char *innobase_log_group_home_dir, *innobase_log_arch_dir;
|
||||||
extern bool innobase_flush_log_at_trx_commit,innobase_log_archive;
|
extern bool innobase_flush_log_at_trx_commit, innobase_log_archive,
|
||||||
|
innobase_use_native_aio;
|
||||||
|
|
||||||
extern TYPELIB innobase_lock_typelib;
|
extern TYPELIB innobase_lock_typelib;
|
||||||
|
|
||||||
@ -176,7 +169,6 @@ bool innobase_init(void);
|
|||||||
bool innobase_end(void);
|
bool innobase_end(void);
|
||||||
bool innobase_flush_logs(void);
|
bool innobase_flush_logs(void);
|
||||||
|
|
||||||
int innobase_commit(THD *thd);
|
int innobase_commit(THD *thd, void* trx_handle);
|
||||||
int innobase_rollback(THD *thd);
|
int innobase_rollback(THD *thd, void* trx_handle);
|
||||||
int innobase_close_connection(THD *thd);
|
int innobase_close_connection(THD *thd);
|
||||||
|
|
||||||
|
@ -952,7 +952,7 @@ void sql_print_error(const char *format,...)
|
|||||||
#ifndef DBUG_OFF
|
#ifndef DBUG_OFF
|
||||||
{
|
{
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
vsprintf(buff,format,args);
|
vsnprintf(buff,sizeof(buff)-1,format,args);
|
||||||
DBUG_PRINT("error",("%s",buff));
|
DBUG_PRINT("error",("%s",buff));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1190,7 +1190,11 @@ static void init_signals(void)
|
|||||||
struct sigaction sa; sa.sa_flags = 0;
|
struct sigaction sa; sa.sa_flags = 0;
|
||||||
sigemptyset(&sa.sa_mask);
|
sigemptyset(&sa.sa_mask);
|
||||||
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
|
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
|
||||||
sa.sa_handler=handle_segfault;
|
#ifdef HAVE_DARWIN_THREADS
|
||||||
|
sa.sa_handler=( void (*)() ) handle_segfault;
|
||||||
|
#else
|
||||||
|
sa.sa_handler=handle_segfault;
|
||||||
|
#endif
|
||||||
sigaction(SIGSEGV, &sa, NULL);
|
sigaction(SIGSEGV, &sa, NULL);
|
||||||
(void) sigemptyset(&set);
|
(void) sigemptyset(&set);
|
||||||
#ifdef THREAD_SPECIFIC_SIGPIPE
|
#ifdef THREAD_SPECIFIC_SIGPIPE
|
||||||
@ -2512,6 +2516,8 @@ CHANGEABLE_VAR changeable_vars[] = {
|
|||||||
#ifdef HAVE_BERKELEY_DB
|
#ifdef HAVE_BERKELEY_DB
|
||||||
{ "bdb_cache_size", (long*) &berkeley_cache_size,
|
{ "bdb_cache_size", (long*) &berkeley_cache_size,
|
||||||
KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
|
KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE },
|
||||||
|
{"bdb_log_buffer_size", (long*) &berkeley_log_buffer_size, 0, 256*1024L,
|
||||||
|
~0L, 0, 1024},
|
||||||
{ "bdb_max_lock", (long*) &berkeley_max_lock,
|
{ "bdb_max_lock", (long*) &berkeley_max_lock,
|
||||||
10000, 0, (long) ~0, 0, 1 },
|
10000, 0, (long) ~0, 0, 1 },
|
||||||
/* QQ: The following should be removed soon! */
|
/* QQ: The following should be removed soon! */
|
||||||
@ -2622,6 +2628,7 @@ struct show_var_st init_vars[]= {
|
|||||||
{"basedir", mysql_home, SHOW_CHAR},
|
{"basedir", mysql_home, SHOW_CHAR},
|
||||||
#ifdef HAVE_BERKELEY_DB
|
#ifdef HAVE_BERKELEY_DB
|
||||||
{"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
|
{"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
|
||||||
|
{"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG},
|
||||||
{"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
|
{"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
|
||||||
{"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
|
{"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG},
|
||||||
{"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
|
{"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR},
|
||||||
@ -2812,7 +2819,7 @@ static void usage(void)
|
|||||||
Don't flush key buffers between writes for any MyISAM\n\
|
Don't flush key buffers between writes for any MyISAM\n\
|
||||||
table\n\
|
table\n\
|
||||||
--enable-locking Enable system locking\n\
|
--enable-locking Enable system locking\n\
|
||||||
-T, --exit-info Print some debug info at exit\n\
|
-T, --exit-info Used for debugging; Use at your own risk!\n\
|
||||||
--flush Flush tables to disk between SQL commands\n\
|
--flush Flush tables to disk between SQL commands\n\
|
||||||
-?, --help Display this help and exit\n\
|
-?, --help Display this help and exit\n\
|
||||||
--init-file=file Read SQL commands from this file at startup\n\
|
--init-file=file Read SQL commands from this file at startup\n\
|
||||||
|
@ -4837,7 +4837,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
|
|||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
** Remove calculation with tables that aren't yet read. Remove also tests
|
** Remove calculation with tables that aren't yet read. Remove also tests
|
||||||
** against fields that are read through key.
|
** against fields that are read through key where the table is not a
|
||||||
|
** outer join table.
|
||||||
** We can't remove tests that are made against columns which are stored
|
** We can't remove tests that are made against columns which are stored
|
||||||
** in sorted order.
|
** in sorted order.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
@ -4853,7 +4854,8 @@ static bool test_if_ref(Item_field *left_item,Item *right_item)
|
|||||||
if (ref_item && ref_item->eq(right_item))
|
if (ref_item && ref_item->eq(right_item))
|
||||||
{
|
{
|
||||||
if (right_item->type() == Item::FIELD_ITEM)
|
if (right_item->type() == Item::FIELD_ITEM)
|
||||||
return field->eq_def(((Item_field *) right_item)->field);
|
return (field->eq_def(((Item_field *) right_item)->field) &&
|
||||||
|
!field->table->maybe_null);
|
||||||
if (right_item->const_item())
|
if (right_item->const_item())
|
||||||
{
|
{
|
||||||
// We can remove binary fields and numerical fields except float,
|
// We can remove binary fields and numerical fields except float,
|
||||||
|
@ -17,7 +17,7 @@ use DBI;
|
|||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
|
|
||||||
$| = 1;
|
$| = 1;
|
||||||
$VER = "2.0";
|
$VER = "2.1";
|
||||||
|
|
||||||
$opt_help = 0;
|
$opt_help = 0;
|
||||||
$opt_version = 0;
|
$opt_version = 0;
|
||||||
@ -40,6 +40,32 @@ my ($dbh, $progname, $mail_no_from_f, $mail_no_txt_f, $mail_too_big,
|
|||||||
|
|
||||||
$mail_no_from_f = $mail_no_txt_f = $mail_too_big = $mail_forwarded =
|
$mail_no_from_f = $mail_no_txt_f = $mail_too_big = $mail_forwarded =
|
||||||
$mail_duplicates = $mail_no_subject_f = $mail_inserted = 0;
|
$mail_duplicates = $mail_no_subject_f = $mail_inserted = 0;
|
||||||
|
$mail_fixed=0;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Remove the following message-ends from message
|
||||||
|
#
|
||||||
|
@remove_tail= (
|
||||||
|
"\n-*\nSend a mail to .*\n.*\n.*\$",
|
||||||
|
"\n-*\nPlease check .*\n.*\n\nTo unsubscribe, .*\n.*\n.*\nIf you have a broken.*\n.*\n.*\$",
|
||||||
|
"\n-*\nPlease check .*\n(.*\n){1,3}\nTo unsubscribe.*\n.*\n.*\$",
|
||||||
|
"\n-*\nPlease check .*\n.*\n\nTo unsubscribe.*\n.*\$",
|
||||||
|
"\n-*\nTo request this thread.*\nTo unsubscribe.*\n.*\.*\n.*\$",
|
||||||
|
"\n -*\n.*Send a mail to.*\n.*\n.*unsubscribe.*\$",
|
||||||
|
"\n-*\nTo request this thread.*\n\nTo unsubscribe.*\n.*\$"
|
||||||
|
);
|
||||||
|
|
||||||
|
# Generate regexp to remove tails where the unsubscribed is quoted
|
||||||
|
{
|
||||||
|
my (@tmp, $tail);
|
||||||
|
@tmp=();
|
||||||
|
foreach $tail (@remove_tail)
|
||||||
|
{
|
||||||
|
$tail =~ s/\n/\n[> ]*/g;
|
||||||
|
push(@tmp, $tail);
|
||||||
|
}
|
||||||
|
push @remove_tail,@tmp;
|
||||||
|
}
|
||||||
|
|
||||||
my %months = ('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5,
|
my %months = ('Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4, 'May' => 5,
|
||||||
'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10,
|
'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9, 'Oct' => 10,
|
||||||
@ -90,7 +116,8 @@ sub main
|
|||||||
push @args, "mysql_socket=$opt_socket" if defined($opt_socket);
|
push @args, "mysql_socket=$opt_socket" if defined($opt_socket);
|
||||||
push @args, "mysql_read_default_group=mail_to_db";
|
push @args, "mysql_read_default_group=mail_to_db";
|
||||||
$connect_arg .= join ';', @args;
|
$connect_arg .= join ';', @args;
|
||||||
$dbh = DBI->connect("$connect_arg", $opt_user, $opt_password)
|
$dbh = DBI->connect("$connect_arg", $opt_user, $opt_password,
|
||||||
|
{ PrintError => 0})
|
||||||
|| die "Couldn't connect: $DBI::errstr\n";
|
|| die "Couldn't connect: $DBI::errstr\n";
|
||||||
|
|
||||||
die "You must specify the database; use --db=" if (!defined($opt_db));
|
die "You must specify the database; use --db=" if (!defined($opt_db));
|
||||||
@ -127,6 +154,7 @@ sub main
|
|||||||
print "Total number of mails:\t\t";
|
print "Total number of mails:\t\t";
|
||||||
print $mail_inserted + $ignored;
|
print $mail_inserted + $ignored;
|
||||||
print "\n";
|
print "\n";
|
||||||
|
print "Mails with unsubscribe removed:\t$mail_fixed\n";
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,6 +307,9 @@ sub date_parser
|
|||||||
print "Inbox filename: $file_name\n";
|
print "Inbox filename: $file_name\n";
|
||||||
}
|
}
|
||||||
exit(1) if ($opt_stop_on_error);
|
exit(1) if ($opt_stop_on_error);
|
||||||
|
$values->{'date'} = "";
|
||||||
|
$values->{'time_zone'} = "";
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
$tmp = $3 . "-" . $months{$2} . "-" . "$1 $4";
|
$tmp = $3 . "-" . $months{$2} . "-" . "$1 $4";
|
||||||
$tmp.= defined($5) ? $5 : ":00";
|
$tmp.= defined($5) ? $5 : ":00";
|
||||||
@ -294,15 +325,29 @@ sub date_parser
|
|||||||
sub update_table
|
sub update_table
|
||||||
{
|
{
|
||||||
my($dbh, $file_name, $values) = @_;
|
my($dbh, $file_name, $values) = @_;
|
||||||
my($q);
|
my($q,$tail,$message);
|
||||||
|
|
||||||
if (!defined($values->{'subject'}) || !defined($values->{'to'}))
|
if (!defined($values->{'subject'}) || !defined($values->{'to'}))
|
||||||
{
|
{
|
||||||
$mail_no_subject_f++;
|
$mail_no_subject_f++;
|
||||||
return; # Ignore these
|
return; # Ignore these
|
||||||
}
|
}
|
||||||
$values->{'message'} =~ s/^\s*//; #removes whitespaces from the beginning
|
$message=$values->{'message'};
|
||||||
$values->{'message'} =~ s/\s*$//; #removes whitespaces from the end
|
$message =~ s/^\s*//; #removes whitespaces from the beginning
|
||||||
|
|
||||||
|
restart:
|
||||||
|
$message =~ s/[\s\n>]*$//; #removes whitespaces and '>' from the end
|
||||||
|
$values->{'message'}=$message;
|
||||||
|
foreach $tail (@remove_tail)
|
||||||
|
{
|
||||||
|
$message =~ s/$tail//;
|
||||||
|
}
|
||||||
|
if ($message ne $values->{'message'})
|
||||||
|
{
|
||||||
|
$message =~ s/\s*$//; #removes whitespaces from the end
|
||||||
|
$mail_fixed++;
|
||||||
|
goto restart; # Some mails may have duplicated messages
|
||||||
|
}
|
||||||
|
|
||||||
$q = "INSERT INTO $opt_table (";
|
$q = "INSERT INTO $opt_table (";
|
||||||
$q.= "mail_id,";
|
$q.= "mail_id,";
|
||||||
@ -320,7 +365,8 @@ sub update_table
|
|||||||
$q.= "NULL,";
|
$q.= "NULL,";
|
||||||
$q.= "'" . $values->{'date'} . "',";
|
$q.= "'" . $values->{'date'} . "',";
|
||||||
$q.= (defined($values->{'time_zone'}) ?
|
$q.= (defined($values->{'time_zone'}) ?
|
||||||
("'" . $values->{'time_zone'} . "',") : "NULL,");
|
$dbh->quote($values->{'time_zone'}) : "NULL");
|
||||||
|
$q.= ",";
|
||||||
$q.= defined($values->{'from'}) ? $dbh->quote($values->{'from'}) : "NULL";
|
$q.= defined($values->{'from'}) ? $dbh->quote($values->{'from'}) : "NULL";
|
||||||
$q.= ",";
|
$q.= ",";
|
||||||
$q.= defined($values->{'reply'}) ? $dbh->quote($values->{'reply'}) : "NULL";
|
$q.= defined($values->{'reply'}) ? $dbh->quote($values->{'reply'}) : "NULL";
|
||||||
@ -331,7 +377,7 @@ sub update_table
|
|||||||
$q.= ",";
|
$q.= ",";
|
||||||
$q.= $dbh->quote($values->{'subject'});
|
$q.= $dbh->quote($values->{'subject'});
|
||||||
$q.= ",";
|
$q.= ",";
|
||||||
$q.= $dbh->quote($values->{'message'});
|
$q.= $dbh->quote($message);
|
||||||
$q.= ",";
|
$q.= ",";
|
||||||
$q.= $dbh->quote($file_name);
|
$q.= $dbh->quote($file_name);
|
||||||
$q.= ",";
|
$q.= ",";
|
||||||
@ -339,12 +385,12 @@ sub update_table
|
|||||||
$q.= ")";
|
$q.= ")";
|
||||||
|
|
||||||
# Don't insert mails bigger than $opt_max_mail_size
|
# Don't insert mails bigger than $opt_max_mail_size
|
||||||
if (length($values->{'message'}) > $opt_max_mail_size)
|
if (length($message) > $opt_max_mail_size)
|
||||||
{
|
{
|
||||||
$mail_too_big++;
|
$mail_too_big++;
|
||||||
}
|
}
|
||||||
# Don't insert mails without 'From' field
|
# Don't insert mails without 'From' field
|
||||||
elsif ($values->{'from'} eq "")
|
elsif (!defined($values->{'from'}) || $values->{'from'} eq "")
|
||||||
{
|
{
|
||||||
$mail_no_from_f++;
|
$mail_no_from_f++;
|
||||||
}
|
}
|
||||||
@ -354,7 +400,7 @@ sub update_table
|
|||||||
$mail_inserted++;
|
$mail_inserted++;
|
||||||
}
|
}
|
||||||
# Don't insert mails without the 'message'
|
# Don't insert mails without the 'message'
|
||||||
elsif ($values->{'message'} eq "")
|
elsif ($message eq "")
|
||||||
{
|
{
|
||||||
$mail_no_txt_f++;
|
$mail_no_txt_f++;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
use DBI;
|
use DBI;
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
|
|
||||||
$VER="1.4a";
|
$VER="1.5";
|
||||||
|
|
||||||
@fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt");
|
@fldnms= ("mail_from","mail_to","cc","date","time_zone","file","sbj","txt");
|
||||||
$fields=8;
|
$fields=8;
|
||||||
@ -18,7 +18,7 @@ $fields=8;
|
|||||||
$opt_user= $opt_password= "";
|
$opt_user= $opt_password= "";
|
||||||
$opt_socket= "/tmp/mysql.sock";
|
$opt_socket= "/tmp/mysql.sock";
|
||||||
$opt_port= 3306;
|
$opt_port= 3306;
|
||||||
$opt_db="test";
|
$opt_db="mail";
|
||||||
$opt_table="mails";
|
$opt_table="mails";
|
||||||
$opt_help=$opt_count=0;
|
$opt_help=$opt_count=0;
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ foreach $val (@fldnms)
|
|||||||
}
|
}
|
||||||
$fields++;
|
$fields++;
|
||||||
}
|
}
|
||||||
$query.= " from $opt_table where $ARGV[0]";
|
$query.= " from $opt_table where $ARGV[0] order by date desc";
|
||||||
|
|
||||||
####
|
####
|
||||||
#### Send query and save result
|
#### Send query and save result
|
||||||
|
Loading…
x
Reference in New Issue
Block a user