Commit d4d22f21 authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com

Merge work:/home/bk/mysql-4.0

into mysql.sashanet.com:/home/sasha/src/bk/mysql-4.0
parents bcc4f3af 423f2851
...@@ -22,4 +22,5 @@ tim@threads.polyesthetic.msg ...@@ -22,4 +22,5 @@ tim@threads.polyesthetic.msg
tim@white.box tim@white.box
tim@work.mysql.com tim@work.mysql.com
tonu@hundin.mysql.fi tonu@hundin.mysql.fi
tonu@x153.internalnet
tonu@x3.internalnet tonu@x3.internalnet
...@@ -498,7 +498,6 @@ MySQL Table Types ...@@ -498,7 +498,6 @@ MySQL Table Types
* HEAP:: HEAP tables * HEAP:: HEAP tables
* InnoDB:: InnoDB tables * InnoDB:: InnoDB tables
* BDB:: BDB or Berkeley_db tables * BDB:: BDB or Berkeley_db tables
* GEMINI:: GEMINI tables
MyISAM Tables MyISAM Tables
...@@ -573,28 +572,6 @@ BDB or Berkeley_DB Tables ...@@ -573,28 +572,6 @@ BDB or Berkeley_DB Tables
* BDB portability:: Operating systems supported by @strong{BDB} * BDB portability:: Operating systems supported by @strong{BDB}
* BDB errors:: Errors You May Get When Using BDB Tables * BDB errors:: Errors You May Get When Using BDB Tables
GEMINI Tables
* GEMINI Overview::
* Using GEMINI Tables::
GEMINI Overview
* GEMINI Features::
* GEMINI Concepts::
* GEMINI Limitations::
Using GEMINI Tables
* Startup Options::
* Creating GEMINI Tables::
* Backing Up GEMINI Tables::
* Restoring GEMINI Tables::
* Using Auto_Increment Columns With GEMINI Tables::
* Performance Considerations::
* Sample Configurations::
* When To Use GEMINI Tables::
MySQL Tutorial MySQL Tutorial
* Connecting-disconnecting:: Connecting to and disconnecting from the server * Connecting-disconnecting:: Connecting to and disconnecting from the server
...@@ -4239,12 +4216,11 @@ phone back within 48 hours to discuss @code{MySQL} related issues. ...@@ -4239,12 +4216,11 @@ phone back within 48 hours to discuss @code{MySQL} related issues.
@cindex support, BDB Tables @cindex support, BDB Tables
@cindex support, InnoDB Tables @cindex support, InnoDB Tables
@cindex support, GEMINI Tables
@node Table handler support, , Telephone support, Support @node Table handler support, , Telephone support, Support
@subsection Support for other table handlers @subsection Support for other table handlers
To get support for @code{BDB} tables, @code{InnoDB} tables or To get support for @code{BDB} tables or @code{InnoDB} tables
@code{GEMINI} tables you have to pay an additional 30% on the standard you have to pay an additional 30% on the standard
support price for each of the table handlers you would like to have support price for each of the table handlers you would like to have
support for. support for.
...@@ -10081,8 +10057,8 @@ reload the grant tables. ...@@ -10081,8 +10057,8 @@ reload the grant tables.
@cindex server, starting problems @cindex server, starting problems
@cindex problems, starting the server @cindex problems, starting the server
If you are going to use tables that support transactions (BDB, InnoDB or If you are going to use tables that support transactions (BDB or InnoDB),
Gemini), you should first create a my.cnf file and set startup options you should first create a my.cnf file and set startup options
for the table types you plan to use. @xref{Table types}. for the table types you plan to use. @xref{Table types}.
Generally, you start the @code{mysqld} server in one of three ways: Generally, you start the @code{mysqld} server in one of three ways:
...@@ -10234,9 +10210,6 @@ options. @xref{InnoDB start}. ...@@ -10234,9 +10210,6 @@ options. @xref{InnoDB start}.
If you are using BDB (Berkeley DB) tables, you should familiarize If you are using BDB (Berkeley DB) tables, you should familiarize
yourself with the different BDB specific startup options. @xref{BDB start}. yourself with the different BDB specific startup options. @xref{BDB start}.
If you are using Gemini tables, refer to the Gemini-specific startup options.
@xref{Using GEMINI Tables}.
@node Automatic start, Command-line options, Starting server, Post-installation @node Automatic start, Command-line options, Starting server, Post-installation
@subsection Starting and Stopping MySQL Automatically @subsection Starting and Stopping MySQL Automatically
@cindex starting, the server automatically @cindex starting, the server automatically
...@@ -11666,8 +11639,8 @@ concerned about transactions. For them transactions are not an ...@@ -11666,8 +11639,8 @@ concerned about transactions. For them transactions are not an
issue. For those of our users who are concerned with or have wondered issue. For those of our users who are concerned with or have wondered
about transactions vis-a-vis @strong{MySQL}, there is a ``@strong{MySQL} about transactions vis-a-vis @strong{MySQL}, there is a ``@strong{MySQL}
way'' as we have outlined above. For those where safety is more way'' as we have outlined above. For those where safety is more
important than speed, we recommend them to use the @code{BDB}, important than speed, we recommend them to use the @code{BDB}
@code{GEMINI} or @code{InnoDB} tables for all their critical or @code{InnoDB} tables for all their critical
data. @xref{Table types}. data. @xref{Table types}.
One final note: We are currently working on a safe replication schema One final note: We are currently working on a safe replication schema
...@@ -11894,12 +11867,11 @@ Entry level SQL92. ODBC levels 0-2. ...@@ -11894,12 +11867,11 @@ Entry level SQL92. ODBC levels 0-2.
@cindex tables, updating @cindex tables, updating
@cindex updating, tables @cindex updating, tables
@cindex @code{BDB} tables @cindex @code{BDB} tables
@cindex @code{GEMINI} tables
@cindex @code{InnoDB} tables @cindex @code{InnoDB} tables
The following mostly applies only for @code{ISAM}, @code{MyISAM}, and The following mostly applies only for @code{ISAM}, @code{MyISAM}, and
@code{HEAP} tables. If you only use transaction-safe tables (@code{BDB}, @code{HEAP} tables. If you only use transaction-safe tables (@code{BDB}
@code{GEMINI} or @code{InnoDB} tables) in an an update, you can do or @code{InnoDB} tables) in an an update, you can do
@code{COMMIT} and @code{ROLLBACK} also with @strong{MySQL}. @code{COMMIT} and @code{ROLLBACK} also with @strong{MySQL}.
@xref{COMMIT}. @xref{COMMIT}.
...@@ -19081,7 +19053,7 @@ When you insert a value of @code{NULL} (recommended) or @code{0} into an ...@@ -19081,7 +19053,7 @@ When you insert a value of @code{NULL} (recommended) or @code{0} into an
If you delete the row containing the maximum value for an If you delete the row containing the maximum value for an
@code{AUTO_INCREMENT} column, the value will be reused with an @code{AUTO_INCREMENT} column, the value will be reused with an
@code{ISAM}, @code{GEMINI} or @code{BDB} table but not with a @code{ISAM} or @code{BDB} table but not with a
@code{MyISAM} or @code{InnoDB} table. If you delete all rows in the table @code{MyISAM} or @code{InnoDB} table. If you delete all rows in the table
with @code{DELETE FROM table_name} (without a @code{WHERE}) in with @code{DELETE FROM table_name} (without a @code{WHERE}) in
@code{AUTOCOMMIT} mode, the sequence starts over for all table types. @code{AUTOCOMMIT} mode, the sequence starts over for all table types.
...@@ -19254,7 +19226,6 @@ The different table types are: ...@@ -19254,7 +19226,6 @@ The different table types are:
@multitable @columnfractions .20 .80 @multitable @columnfractions .20 .80
@item BDB or Berkeley_db @tab Transaction-safe tables with page locking. @xref{BDB}. @item BDB or Berkeley_db @tab Transaction-safe tables with page locking. @xref{BDB}.
@item GEMINI @tab Transaction-safe tables with row-level locking @xref{GEMINI}.
@item HEAP @tab The data for this table is only stored in memory. @xref{HEAP}. @item HEAP @tab The data for this table is only stored in memory. @xref{HEAP}.
@item ISAM @tab The original table handler. @xref{ISAM}. @item ISAM @tab The original table handler. @xref{ISAM}.
@item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}. @item InnoDB @tab Transaction-safe tables with row locking. @xref{InnoDB}.
...@@ -22978,8 +22949,8 @@ By default, @strong{MySQL} runs in @code{autocommit} mode. This means that ...@@ -22978,8 +22949,8 @@ By default, @strong{MySQL} runs in @code{autocommit} mode. This means that
as soon as you execute an update, @strong{MySQL} will store the update on as soon as you execute an update, @strong{MySQL} will store the update on
disk. disk.
If you are using transactions safe tables (like @code{BDB}, If you are using transactions safe tables (like @code{BDB} or
@code{InnoDB} or @code{GEMINI}), you can put @strong{MySQL} into @code{InnoDB}), you can put @strong{MySQL} into
non-@code{autocommit} mode with the following command: non-@code{autocommit} mode with the following command:
@example @example
...@@ -23862,7 +23833,6 @@ used them. ...@@ -23862,7 +23833,6 @@ used them.
@cindex table types, choosing @cindex table types, choosing
@cindex @code{BDB} table type @cindex @code{BDB} table type
@cindex @code{Berkeley_db} table type @cindex @code{Berkeley_db} table type
@cindex @code{GEMINI} table type
@cindex @code{HEAP} table type @cindex @code{HEAP} table type
@cindex @code{ISAM} table type @cindex @code{ISAM} table type
@cindex @code{InnoDB} table type @cindex @code{InnoDB} table type
...@@ -23875,8 +23845,8 @@ used them. ...@@ -23875,8 +23845,8 @@ used them.
As of @strong{MySQL} Version 3.23.6, you can choose between three basic As of @strong{MySQL} Version 3.23.6, you can choose between three basic
table formats (@code{ISAM}, @code{HEAP} and @code{MyISAM}. Newer table formats (@code{ISAM}, @code{HEAP} and @code{MyISAM}. Newer
@strong{MySQL} may support additional table type (@code{BDB}, @strong{MySQL} may support additional table type (@code{BDB}
@code{GEMINI} or @code{InnoDB}), depending on how you compile it. or @code{InnoDB}), depending on how you compile it.
When you create a new table, you can tell @strong{MySQL} which table When you create a new table, you can tell @strong{MySQL} which table
type it should use for the table. @strong{MySQL} will always create a type it should use for the table. @strong{MySQL} will always create a
...@@ -23901,8 +23871,8 @@ You can convert tables between different types with the @code{ALTER ...@@ -23901,8 +23871,8 @@ You can convert tables between different types with the @code{ALTER
TABLE} statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}. TABLE} statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}.
Note that @strong{MySQL} supports two different kinds of Note that @strong{MySQL} supports two different kinds of
tables. Transaction-safe tables (@code{BDB}, @code{InnoDB} or tables. Transaction-safe tables (@code{BDB} or @code{InnoDB})
@code{GEMINI}) and not transaction-safe tables (@code{HEAP}, @code{ISAM}, and not transaction-safe tables (@code{HEAP}, @code{ISAM},
@code{MERGE}, and @code{MyISAM}). @code{MERGE}, and @code{MyISAM}).
Advantages of transaction-safe tables (TST): Advantages of transaction-safe tables (TST):
...@@ -23944,7 +23914,6 @@ of both worlds. ...@@ -23944,7 +23914,6 @@ of both worlds.
* HEAP:: HEAP tables * HEAP:: HEAP tables
* InnoDB:: InnoDB tables * InnoDB:: InnoDB tables
* BDB:: BDB or Berkeley_db tables * BDB:: BDB or Berkeley_db tables
* GEMINI:: GEMINI tables
@end menu @end menu
@node MyISAM, MERGE, Table types, Table types @node MyISAM, MERGE, Table types, Table types
...@@ -26000,7 +25969,7 @@ Finland ...@@ -26000,7 +25969,7 @@ Finland
@cindex tables, @code{BDB} @cindex tables, @code{BDB}
@cindex tables, @code{Berkeley DB} @cindex tables, @code{Berkeley DB}
@node BDB, GEMINI, InnoDB, Table types @node BDB, , InnoDB, Table types
@section BDB or Berkeley_DB Tables @section BDB or Berkeley_DB Tables
@menu @menu
...@@ -26285,856 +26254,6 @@ not in @code{auto_commit} mode, until this problem is fixed (the fix is ...@@ -26285,856 +26254,6 @@ not in @code{auto_commit} mode, until this problem is fixed (the fix is
not trivial). not trivial).
@end itemize @end itemize
@cindex GEMINI tables
@node GEMINI, , BDB, Table types
@section GEMINI Tables
@cindex GEMINI tables, overview
@menu
* GEMINI Overview::
* Using GEMINI Tables::
@end menu
@node GEMINI Overview, Using GEMINI Tables, GEMINI, GEMINI
@subsection GEMINI Overview
GEMINI is currently not included in the @strong{MySQL} 3.23 distribution
because it's not to our knowledge an open source (GPL) product.
@code{GEMINI} is a transaction-safe table handler for @strong{MySQL}. It
provides row-level locking, robust transaction support and reliable
crash recovery. It is targeted for databases that need to handle heavy
multi-user updates typical of transaction processing applications while
still providing excellent performance for read-intensive operations. The
@code{GEMINI} table type is developed and supported by NuSphere
Corporation (see @url{http://www.nusphere.com}).
@code{GEMINI} provides full ACID transaction properties (Atomic,
Consistent, Independent, and Durable) with a programming model that
includes support for statement atomicity and all four standard isolation
levels (Read Uncommitted, Read Committed, Repeatable Read, and
Serializable) defined in the SQL standard.
The @code{GEMINI} tables support row-level and table-level locking to
increase concurrency in applications and allow reading of tables without
locking for maximum concurrency in a heavy update environment. The
transaction, locking, and recovery mechanisms are tightly integrated to
eliminate unnecessary administration overhead.
In general, if @code{GEMINI} tables are selected for an application, it
is recommended that all tables updated in the application be
@code{GEMINI} tables to provide well-defined system behavior. If
non-@code{GEMINI} tables are mixed into the application then, ACID
transaction properties cannot be maintained. While there are clearly
cases where mixing table types is appropriate, it should always be done
with careful consideration of the impact on transaction consistency and
recoverability needs of the application and underlying database.
The @code{GEMINI} table type is derived from a successful commercial
database and uses the storage kernel technology tightly integrated with
@strong{MySQL} server. The basic @code{GEMINI} technology is in use by
millions of users worldwide in production environments today. This
maturity allows @code{GEMINI} tables to provide a solution for those
users who require transaction-based behavior as part of their
applications.
The @code{GEMINI} table handler supports a configurable data cache that
allows a significant portion of any database to be maintained in memory
while still allowing durable updates.
@cindex GEMINI tables, features
@menu
* GEMINI Features::
* GEMINI Concepts::
* GEMINI Limitations::
@end menu
@node GEMINI Features, GEMINI Concepts, GEMINI Overview, GEMINI Overview
@subsubsection GEMINI Features
The following summarizes the major features provided by @code{GEMINI}
tables.
@itemize @bullet
@item
Supports all optimization statistics used by the @strong{MySQL} optimizer
including table cardinality, index range estimates and multi-component
selectivity to insure optimal query performance.
@item
Maintains exact cardinality information for each table so @code{SELECT
COUNT(*) FROM} table-name always returns an answer immediately.
@item
Supports index-only queries; when index data is sufficient to resolve a
query no record data is read (for non character types).
@item
@code{GEMINI} uses block based I/O for better performance. There is no
performance penalty for using @code{VARCHAR} fields. The maximum record size is
currently 32K.
@item
The number of rows in a single @code{GEMINI} table can be 4 quintillion
(full use of 64 bits).
@item
Individual tables can be as large as 16 petabytes.
@item
Locking is done at a record or row level rather than at table level
unless table locks are explicitly requested. When a row is inserted into
a table, other rows can be updated, inserted or deleted without waiting
for the inserted row to be committed.
@item
Provides durable transactions backed by a crash recovery mechanism that
returns the database to a known consistent state in the event of an
unexpected failure.
@item
Support for all isolation levels and statement atomicity defined in the
SQL standard.
@item
Reliable Master Replication; the master database can survive system
failure and recover all committed transactions.
@end itemize
@cindex GEMINI tables, concepts
@node GEMINI Concepts, GEMINI Limitations, GEMINI Features, GEMINI Overview
@subsubsection GEMINI Concepts
This section highlights some of the important concepts behind
@code{GEMINI} and the @code{GEMINI} programming model, including:
@itemize @bullet
@item
ACID Transactions
@item
Transaction COMMIT/ROLLBACK
@item
Statement Atomicity
@item
Recovery
@item
Isolation Levels
@item
Row-Level Locking
@end itemize
These features are described below.
@cindex GEMINI tables, ACID transactions
@noindent
@strong{ACID Transactions}
ACID in the context of transactions is an acronym which stands for
@emph{Atomicity}, @emph{Consistency}, @emph{Isolation}, @emph{Durability}.
@multitable @columnfractions .25 .75
@item @sc{Attribute} @tab @sc{Description}
@item
@strong{Atomicity}
@tab A transaction allows for the grouping of one or more changes to
tables and rows in the database to form an atomic or indivisible
operation. That is, either all of the changes occur or none of them
do. If for any reason the transaction cannot be completed, everything
this transaction changed can be restored to the state it was in prior to
the start of the transaction via a rollback operation.
@item
@strong{Consistency}
@tab
Transactions always operate on a consistent view of the data and when
they end always leave the data in a consistent state. Data may be said to
be consistent as long as it conforms to a set of invariants, such as no
two rows in the customer table have the same customer ID and all orders
have an associated customer row. While a transaction executes, these
invariants may be violated, but no other transaction will be allowed to
see these inconsistencies, and all such inconsistencies will have been
eliminated by the time the transaction ends.
@item
@strong{Isolation}
@tab To a given transaction, it should appear as though it is running
all by itself on the database. The effects of concurrently running
transactions are invisible to this transaction, and the effects of this
transaction are invisible to others until the transaction is committed.
@item
@strong{Durability}
@tab Once a transaction is committed, its effects are guaranteed to
persist even in the event of subsequent system failures. Until the
transaction commits, not only are any changes made by that transaction
not durable, but are guaranteed not to persist in the face of a system
failures, as crash recovery will rollback their effects.
@end multitable
@cindex GEMINI tables, COMMIT/ROLLBACK
@noindent
@strong{Transaction COMMIT/ROLLBACK}
As stated above, a transaction is a group of work being done to
data. Unless otherwise directed, @strong{MySQL} considers each statement
a transaction in itself. Multiple updates can be accomplished by placing
them in a single statement, however they are limited to a single table.
Applications tend to require more robust use of transaction
concepts. Take, for example, a system that processes an order: A row may
be inserted in an order table, additional rows may be added to an
order-line table, updates may be made to inventory tables, etc. It is
important that if the order completes, all the changes are made to all
the tables involved; likewise if the order fails, none of the changes to
the tables must occur. To facilitate this requirement, @strong{MySQL}
has syntax to start a transaction called @code{BEGIN WORK}. All
statements that occur after the @code{BEGIN WORK} statement are grouped
into a single transaction. The end of this transaction occurs when a
@code{COMMIT} or @code{ROLLBACK} statement is encountered. After the
@code{COMMIT} or @code{ROLLBACK} the system returns back to the behavior
before the @code{BEGIN WORK} statement was encountered where every
statement is a transaction.
To permanently turn off the behavior where every statement is a
transaction, @strong{MySQL} added a variable called
@code{AUTOCOMMIT}. The @code{AUTOCOMMIT} variable can have two values,
@code{1} and @code{0}. The mode where every statement is a transaction
is when @code{AUTOCOMMIT} is set to @code{1} (@code{AUTOCOMMIT=1}). When
@code{AUTOCOMMIT} is set to @code{0} (@code{AUTOCOMMIT=0}), then every
statement is part of the same transaction until the transaction end by
either @code{COMMIT} or @code{ROLLBACK}. Once a transaction completes, a
new transaction is immediately started and the process repeats.
Here is an example of the SQL statements that you may find in a typical
order:
@example
BEGIN WORK;
INSERT INTO order VALUES ...;
INSERT INTO order-lines VALUES ...;
INSERT INTO order-lines VALUES ...;
INSERT INTO order-lines VALUES ...;
UPDATE inventory WHERE ...;
COMMIT;
@end example
This example shows how to use the @code{BEGIN WORK} statement to start a
transaction. If the variable @code{AUTOCOMMIT} is set to @code{0}, then
a transaction would have been started already. In this case, the
@code{BEGIN WORK} commits the current transaction and starts a new one.
@cindex GEMINI tables, statement atomicity
@noindent
@strong{Statement Atomicity}
As mentioned above, when running with @code{AUTOCOMMIT} set to @code{1},
each statement executes as a single transaction. When a statement has an
error, then all changes make by the statement must be
undone. Transactions support this behavior. Non-transaction safe table
handlers would have a partial statement update where some of the changes
from the statement would be contained in the database and other changes
from the statement would not. Work would need to be done to manually
recover from the error.
@cindex GEMINI tables, recovery
@noindent
@strong{Recovery}
Transactions are the basis for database recovery. Recovery is what
supports the Durability attribute of the ACID transaction.
@code{GEMINI} uses a separate file called the Recovery Log located in
the @code{$DATADIR} directory named @code{gemini.rl}. This file
maintains the integrity of all the @code{GEMINI} tables. @code{GEMINI}
can not recover any data from non-@code{GEMINI} tables. In addition, the
@code{gemini.rl} file is used to rollback transactions in support of the
@code{ROLLBACK} statement.
In the event of a system failure, the next time the @strong{MySQL}
server is started, @code{GEMINI} will automatically go through its
crash recovery process. The result of crash recovery is that all the
@code{GEMINI} tables will contain the latest changes made to them, and
all transactions that were open at the time of the crash will have been
rolled back.
The @code{GEMINI} Recovery Log reuses space when it can. Space can be
reused when information in the Recovery Log is no longer needed for
crash recovery or rollback.
@cindex GEMINI tables, isolation levels
@noindent
@strong{Isolation Levels}
There are four isolation levels supported by @code{GEMINI}:
@itemize @bullet
@item
READ UNCOMMITTED
@item
READ COMMITTED
@item
REPEATABLE READ
@item
SERIALIZABLE
@end itemize
These isolation levels apply only to shared locks obtained by select
statements, excluding select for update. Statements that get exclusive
locks always retain those locks until the transaction commits or rolls
back.
By default, @code{GEMINI} operates at the @code{READ COMMITTED}
level. You can override the default using the following command:
@example
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE ]
@end example
If the @code{SESSION} qualifier used, the specified isolation level
persists for the entire session. If the @code{GLOBAL} qualifier is used,
the specified isolation level is applied to all new connections from
this point forward. Note that the specified isolation level will not
change the behavior for existing connections including the connection
that exectues the @code{SET GLOBAL TRANSACTION ISOLATION LEVEL}
statement.
@multitable @columnfractions .30 .70
@item @sc{Isolation Level} @tab @sc{Description}
@item
@strong{READ UNCOMMITTED}
@tab Does not obtain any locks when reading rows. This means that if a
row is locked by another process in a transaction that has a more strict
isolation level, the @code{READ UNCOMMITTED} query will not wait until
the locks are released before reading the row. You will get an error if
attempt any updates while running at this isolation level.
@item
@strong{READ COMMITTED}
@tab Locks the requested rows long enough to copy the row from the
database block to the client row buffer. If a @code{READ COMMITTED}
query finds that a row is locked exclusively by another process, it will
wait until either the row has been released, or the lock timeout value
has expired.
@item
@strong{REPEATABLE READ}
@tab Locks all the rows needed to satisfy the query. These locks are
held until the transaction ends (commits or rolls back). If a
@code{REPEATABLE READ} query finds that a row is locked exclusively by
another process, it will wait until either the row has been released, or
the lock timeout value has expired.
@item
@strong{SERIALIZABLE}
@tab Locks the table that contains the rows needed to satisfy the
query. This lock is held until the transaction ends (commits or rolls
back). If a @code{SERIALIZABLE} query finds that a row is exclusively
locked by another process, it will wait until either the row has been
released, or the lock timeout value has expired.
@end multitable
The statements that get exclusive locks are @code{INSERT},
@code{UPDATE}, @code{DELETE} and @code{SELECT ... FOR UPDATE}. Select
statements without the @code{FOR UPDATE} qualifier get shared locks
which allow other not ''for update'' select statements to read the same
rows but block anyone trying to update the row from accessing it. Rows
or tables with exclusive locks block all access to the row from other
transactions until the transaction ends.
In general terms, the higher the Isolation level the more likelihood of
having concurrent locks and therefore lock conflicts. In such cases,
adjust the @code{-O gemini_lock_table_size} accordingly.
@cindex GEMINI tables, row-level locking
@noindent
@strong{Row-Level Locking}
@code{GEMINI} uses row locks, which allows high concurrency for requests
on the same table.
In order to avoid lock table overflow, SQL statements that require
applying locks to a large number of rows should either be run at the
serializable isolation level or should be covered by a lock table
statement.
Memory must be pre-allocated for the lock table. The mysqld server
startup option @code{-0 gemini_lock_table_size} can be used to adjust
the number of concurrent locks.
@cindex GEMINI tables, limitations
@node GEMINI Limitations, , GEMINI Concepts, GEMINI Overview
@subsubsection GEMINI Limitations
The following limitations are in effect for the current version of
@code{GEMINI}:
@itemize @bullet
@item
@code{DROP DATABASE} does not work with @code{GEMINI} tables; instead,
drop all the tables in the database first, then drop the database.
@item
Maximum number of @code{GEMINI} tables is 1012.
@item
Maximum number of @code{GEMINI} files a server can manage is 1012. Each
table consumes one file; an additional file is consumed if the table has
any indexes defined on it.
@item
Maximum size of BLOBs is 16MB.
@item
@code{FULLTEXT} indexes are not supported with @code{GEMINI} tables.
@item
There is no support for multi-component @code{AUTO_INCREMENT} fields
that provide alternating values at the component level. If you try to
create such a field, @code{GEMINI} will refuse.
@item
@code{TEMPORARY TABLES} are not supported by @code{GEMINI}. The
statement @code{CREATE TEMPORARY TABLE ... TYPE=GEMINI} will generate
the response: @code{ERROR 1005: Can't create table '/tmp/#sqlxxxxx'
(errno: 0)}.
@item
@code{FLUSH TABLES} has not been implemented with @code{GEMINI} tables.
@end itemize
@cindex GEMINI tables, using
@node Using GEMINI Tables, , GEMINI Overview, GEMINI
@subsection Using GEMINI Tables
This section explains the various startup options you can use with
@code{GEMINI} tables, how to backup @code{GEMINI} tables, some
performance considerations and sample configurations, and a brief
discussion of when to use @code{GEMINI} tables.
Specifically, the topics covered in this section are:
@itemize @bullet
@item
Startup Options
@item
Creating @code{GEMINI} Tables
@item
Backing Up @code{GEMINI} Tables
@item
Using Auto_Increment Columns With @code{GEMINI} Tables
@item
Performance Considerations
@item
Sample Configurations
@item
When To Use @code{GEMINI} Tables
@end itemize
@cindex GEMINI tables, startup options
@menu
* Startup Options::
* Creating GEMINI Tables::
* Backing Up GEMINI Tables::
* Restoring GEMINI Tables::
* Using Auto_Increment Columns With GEMINI Tables::
* Performance Considerations::
* Sample Configurations::
* When To Use GEMINI Tables::
@end menu
@node Startup Options, Creating GEMINI Tables, Using GEMINI Tables, Using GEMINI Tables
@subsubsection Startup Options
The table below lists options to mysqld that can be used to change the
behavior of @code{GEMINI} tables.
@multitable @columnfractions .40 .60
@item @sc{Option} @tab @sc{Description}
@item
@code{--default-table-type=gemini}
@tab Sets the default table handler to be @code{GEMINI}. All create
table statements will create @code{GEMINI} tables unless otherwise
specified with @code{TYPE=@var{table-type}}. As noted above, there is
currently a limitation with @code{TEMPORARY} tables using @code{GEMINI}.
@item
@code{--gemini-flush-log-at-commit}
@tab Forces the recovery log buffers to be flushed after every
commit. This can have a serious performance penalty, so use with
caution.
@item
@code{--gemini-recovery=FULL | NONE | FORCE}
@tab Sets the recovery mode. Default is @code{FULL}. @code{NONE} is
useful for performing repeatable batch operations because the updates
are not recorded in the recovery log. @code{FORCE} skips crash recovery
upon startup; this corrupts the database, and should be used in
emergencies only.
@item
@code{--gemini-unbuffered-io}
@tab All database writes bypass the OS cache. This can provide a
performance boost on heavily updated systems where most of the dataset
being worked on is cached in memory with the @code{gemini_buffer_cache}
parameter.
@item
@code{--O gemini_buffer_cache=size}
@tab Amount of memory to allocate for database buffers, including Index
and Record information. It is recommended that this number be 10% of the
total size of all @code{GEMINI} tables. Do not exceed amount of memory
on the system!
@item
@code{--O gemini_connection_limit=#}
@tab Maximum number of connections to @code{GEMINI}; default is
@code{100}. Each connection consumes about 1K of memory.
@item
@code{--O gemini_io_threads=#}
@tab Number of background I/O threads; default is @code{2}. Increase the
number when using @code{--gemini-unbuffered-io}
@item
@code{--O gemini_lock_table_size=#}
@tab Sets the maximum number of concurrent locks; default is 4096. Using
@code{SET [ GLOBAL | SESSION ] TRANSACTION ISOLATION = ...} will
determine how long a program will hold row locks.
@item
@code{--O gemini_lock_wait_timeout=seconds}
@tab Number of seconds to wait for record locks when performing queries;
default is 10 seconds. Using @code{SET [ GLOBAL | SESSION ] TRANSACTION
ISOLATION = ...} will determine how long a program will hold row locks.
@item
@code{--skip-gemini}
@tab Do not use @code{GEMINI}. If you use @code{--skip-gemini}, @strong{MySQL}
will not initialize the @code{GEMINI} table handler, saving memory; you
cannot use @code{GEMINI} tables if you use @code{--skip-gemini}.
@item
@code{--transaction-isolation=READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE}
@tab Sets the GLOBAL transaction isolation level for all users that
connect to the server; can be overridden with the SET ISOLATION LEVEL
statement.
@end multitable
@cindex GEMINI tables, creating
@node Creating GEMINI Tables, Backing Up GEMINI Tables, Startup Options, Using GEMINI Tables
@subsubsection Creating GEMINI Tables
@code{GEMINI} tables can be created by either using the @code{CREATE
TABLE} syntax or the @code{ALTER TABLE} syntax.
@itemize @bullet
@item
The syntax for creating a @code{GEMINI} table is:
@example
CREATE TABLE @var{table-name} (....) TYPE=GEMINI;
@end example
@item
The syntax to convert a table to @code{GEMINI} is:
@example
ALTER TABLE @var{table-name} TYPE=GEMINI;
@end example
@end itemize
@xref{Tutorial}, for more information on how to create and use
@code{MySQL} tables.
@cindex GEMINI tables, backing up
@node Backing Up GEMINI Tables, Restoring GEMINI Tables, Creating GEMINI Tables, Using GEMINI Tables
@subsubsection Backing Up GEMINI Tables
@code{GEMINI} supports both @code{BACKUP TABLE} and @code{RESTORE TABLE}
syntax. To learn more about how to use @code{BACKUP} and @code{RESTORE},
see @ref{BACKUP TABLE} and @ref{RESTORE TABLE}.
To backup @code{GEMINI} tables outside of the @code{MySQL} environment,
you must first shut down the @code{MySQL} server. Once the server is
shut down, you can copy the files associated with @code{GEMINI} to a
different location. The files that make up the @code{GEMINI} table
handler are:
@itemize @bullet
@item
All files associated with a table with a @code{.gmd} extention below the
@code{$DATADIR} directory. Such files include @code{@var{table}.gmd},
@code{@var{table}.gmi}, and @code{@var{table}.frm}
@item
@code{gemini.db} in the @code{$DATADIR} directory
@item
@code{gemini.rl} in the @code{$DATADIR} directory
@item
@code{gemini.lg} in the @code{$DATADIR} directory
@end itemize
All the @code{GEMINI} files must be copied together. You can not copy
just the @code{.gmi} and @code{.gmd} files to a different
@code{$DATADIR} and have them become part of a new database. You can
copy an entire @code{$DATADIR} directory to another location and start a
@strong{MySQL} server using the new @code{$DATADIR}.
@cindex GEMINI tables, restoring
@node Restoring GEMINI Tables, Using Auto_Increment Columns With GEMINI Tables, Backing Up GEMINI Tables, Using GEMINI Tables
@subsubsection Restoring GEMINI Tables
To restore @code{GEMINI} tables outside of the @code{MySQL} environment,
you must first shut down the @code{MySQL} server. Once the server is
shut down, you can remove all @code{GEMINI} files in the target
@code{$DATADIR} and then copy the files previously backed up into the
@code{$DATADIR} directory.
As mentioned above, the files that make up the @code{GEMINI} table
handler are:
@itemize @bullet
@item
All files associated with a table with a @code{.gmd} extention below the
@code{$DATADIR} directory. Such files include @code{@var{table}.gmd},
@code{@var{table}.gmi}, and @code{@var{table}.frm}
@item
@code{gemini.db} in the @code{$DATADIR} directory
@item
@code{gemini.rl} in the @code{$DATADIR} directory
@item
@code{gemini.lg} in the @code{$DATADIR} directory
@end itemize
When restoring a table, all the @code{GEMINI} files must be copied
together. You can not restore just the @code{.gmi} and @code{.gmd}
files.
@cindex GEMINI tables, auto_increment
@node Using Auto_Increment Columns With GEMINI Tables, Performance Considerations, Restoring GEMINI Tables, Using GEMINI Tables
@subsubsection Using Auto_Increment Columns With GEMINI Tables
As mentioned previously, @code{GEMINI} tables support row-level and
table-level locking to increase concurrency in applications and to allow
reading of tables without locking for maximum concurrency in heavy
update environments. This feature has several implications when working
with @code{auto_increment} tables.
In @code{MySQL}, when a column is defined as an @code{auto_increment}
column, and a row is inserted into the table with a @code{NULL} for the
column, the @code{auto_increment} column is updated to be 1 higher than
the highest value in the column.
With @code{MyISAM} tables, the @code{auto_increment} function is
implemented by looking in the index and finding the highest value and
adding 1 to it. This is possible because the entire @code{ISAM} table is
locked during the update period and the increment value is therefore
guaranteed to not be changing.
With @code{GEMINI} tables, the @code{auto_increment} function is
implemented by maintaining a counter in a separate location from the
table data. Instead of looking at the highest value in the table index,
@code{GEMINI} tables look at this separately maintained counter. This
means that in a transactional model, unlike the bottleneck inherent in
the @code{MyISAM} approach, @code{GEMINI} users do @b{not} have to wait
until the transaction that added the last value either commits or
rollbacks before looking at the value.
Two side-effects of the @code{GEMINI} implementation are:
@itemize @bullet
@item
If an insert is done where the column with the @code{auto_increment} is
specified, and this specified value is the highest value, @code{MyISAM}
uses it as its @code{auto_increment} value, and every subsequent insert
is based on this. By contrast, @code{GEMINI} does not use this value,
but instead uses the value maintained in the separate @code{GEMINI}
counter location.
@item
To set the counter to a specific value, you can use @code{SET
insert_id=#} and insert a new row in the table. However, as a general
rule, values should not be inserted into an @code{auto_increment}
column; the database manager should be maintaining this field, not the
application. @code{SET insert_id} is a recovery mechanism that should be
used in case of error only.
@end itemize
Note that if you delete the row containing the maximum value for an
@code{auto_increment} column, the value will be reused with a
@code{GEMINI} table but not with a @code{MyISAM} table.
See @ref{CREATE TABLE} for more information about creating
@code{auto_increment} columns.
@cindex GEMINI tables, peformance considerations
@node Performance Considerations, Sample Configurations, Using Auto_Increment Columns With GEMINI Tables, Using GEMINI Tables
@subsubsection Performance Considerations
In addition to designing the best possible application, configuration of
the data and the server startup parameters need to be considered. How
the hardware is being used can have a dramatic affect on how fast the
system will respond to queries. Disk Drives and Memory must both be
considered.
@noindent
@strong{Disk Drives}
For best performance, you want to spread the data out over as many disks
as possible. Using RAID 10 stripes work very well. If there are a lot of
updates then the recovery log (@code{gemini.rl}) should be on a
relatively quiet disk drive.
To spread the data out without using RAID 10, you can do the following:
@itemize @bullet
@item
Group all the tables into three categories: Heavy Use, Moderate Use,
Light Use.
@item
Take the number of disk drives available and use a round-robin approach
to the three categories grouping the tables on a disk drive. The result
will be an equal distribution of Heavy/Moderate/Light tables assigned to
each disk drive.
@item
Once the tables have been converted to @code{GEMINI} by using the
@code{ALTER TABLE <name> TYPE=GEMINI} statements, move (@code{mv}) the
@code{.gmd} and @code{.gmi} files to a different disk drive and link
(@code{ln -s}) them back to the original directory where the @code{.frm}
file resides.
@item
Finally, move the @code{gemini.rl} file to its quiet disk location and link
the file back to the @code{$DATADIR} directory.
@end itemize
@noindent
@strong{Memory}
The more data that can be placed in memory the faster the access to the
data. Figure out how large the @code{GEMINI} data is by adding up the
@code{.gmd} and @code{.gmi} file sizes. If you can, put at least 10% of
the data into memory. You allocate memory for the rows and indexes by
using the @code{gemini_buffer_cache} startup parameter. For example:
@example
mysqld -O gemini_buffer_cache=800M
@end example
@noindent
would allocate 800 MB of memory for the @code{GEMINI} buffer cache.
@cindex GEMINI tables, sample configurations
@node Sample Configurations, When To Use GEMINI Tables, Performance Considerations, Using GEMINI Tables
@subsubsection Sample Configurations
Based on the performance considerations above, we can look at some
examples for how to get the best performance out of the system when
using @code{GEMINI} tables.
@multitable @columnfractions .30 .70
@item @sc{Hardware} @tab @sc{Configuration}
@item
One CPU, 128MB memory, one disk drive
@tab Allocate 80MB of memory for reading and updating @code{GEMINI}
tables by starting the mysqld server with the following option:
@example
-O gemini_buffer_cache=80M
@end example
@item
Two CPUs, 512MB memory, four disk drives
@tab Use RAID 10 to stripe the data across all available disks, or use
the method described in the performance considerations section,
above. Allocate 450MB of memory for reading/updating @code{GEMINI}
tables:
@example
-O gemini_buffer_cache=450M
@end example
@end multitable
@cindex GEMINI tables, when to use
@node When To Use GEMINI Tables, , Sample Configurations, Using GEMINI Tables
@subsubsection When To Use GEMINI Tables
Because the @code{GEMINI} table handler provides crash recovery and
transaction support, there is extra overhead that is not found in other
non-transaction safe table handlers. Here are some general guidelines
for when to employ @code{GEMINI} and when to use other non-transaction
safe tables (@code{NTST}).
Note that in the following table, you could instead of GEMINI use
InnoDB or BDB tables.
@multitable @columnfractions .30 .25 .45
@item
@sc{Access Trends} @tab @sc{Table Type} @tab @sc{Reason}
@item
Read-only
@tab @code{NTST}
@tab Less overhead and faster
@item
Critical data
@tab @code{GEMINI}
@tab Crash recovery protection
@item
High concurrency
@tab @code{GEMINI}
@tab Row-level locking
@item
Heavy update
@tab @code{GEMINI}
@tab Row-level locking
@end multitable
The table below shows how a typical application schema could be defined.
@multitable @columnfractions .15 .30 .25 .30
@item
@sc{Table} @tab @sc{Contents} @tab @sc{Table Type} @tab @sc{Reason}
@item
account
@tab Customer account data
@tab @code{GEMINI}
@tab Critical data, heavy update
@item
order
@tab Orders for a customer
@tab @code{GEMINI}
@tab Critical data, heavy update
@item
orderline
@tab Orderline detail for an order
@tab @code{GEMINI}
@tab Critical data, heavy update
@item
invdesc
@tab Inventory description
@tab @code{NTST}
@tab Read-only, frequent access
@item
salesrep
@tab Sales rep information
@tab @code{NTST}
@tab Infrequent update
@item
inventory
@tab Inventory information
@tab @code{GEMINI}
@tab High concurrency, critical data
@item
config
@tab System configuration
@tab @code{NTST}
@tab Read-only
@end multitable
@cindex tutorial @cindex tutorial
@cindex terminal monitor, defined @cindex terminal monitor, defined
@cindex monitor, terminal @cindex monitor, terminal
...@@ -44109,8 +43228,8 @@ included in the source. ...@@ -44109,8 +43228,8 @@ included in the source.
applications that need all speed they can get. The tables may be memory applications that need all speed they can get. The tables may be memory
based,@code{HEAP} tables or disk based @code{MyISAM}. @xref{Table types}. based,@code{HEAP} tables or disk based @code{MyISAM}. @xref{Table types}.
@item @item
@strong{MySQL} has support for 3 different table handles that support @strong{MySQL} has support for 2 different table handles that support
transactions (@code{BDB}, @code{InnoDB} and @code{Gemini}. Because transactions (@code{BDB} and @code{InnoDB}). Because
every transaction engine performs differently under different every transaction engine performs differently under different
conditions, this gives the application writer more options to find an conditions, this gives the application writer more options to find an
optimal solution for his/her setup. @xref{Table types}. optimal solution for his/her setup. @xref{Table types}.
...@@ -46654,10 +45773,6 @@ transaction-safe tables. ...@@ -46654,10 +45773,6 @@ transaction-safe tables.
@item @strong{InnoDB} @item @strong{InnoDB}
A transaction-safe table handler that supports row level locking, and many A transaction-safe table handler that supports row level locking, and many
Oracle-like features. Oracle-like features.
@c change "three" to "four" above when uncommenting this
@c @item Gemini
@c A transaction-safe, row-level locking table handler that supports many
@c features required in a mission-critical environment.
@end table @end table
Note that only MyISAM is available in the standard binary distribution. Note that only MyISAM is available in the standard binary distribution.
...@@ -22,7 +22,7 @@ TAR = gtar ...@@ -22,7 +22,7 @@ TAR = gtar
EXTRA_DIST = INSTALL-SOURCE README \ EXTRA_DIST = INSTALL-SOURCE README \
COPYING COPYING.LIB MIRRORS COPYING COPYING.LIB MIRRORS
SUBDIRS = include @docs_dirs@ @readline_dir@ \ SUBDIRS = include @docs_dirs@ @readline_dir@ \
@thread_dirs@ @pstack_dirs@ vio @sql_client_dirs@ \ @thread_dirs@ @pstack_dirs@ @sql_client_dirs@ \
@sql_server_dirs@ @libmysqld_dirs@ scripts tests man \ @sql_server_dirs@ @libmysqld_dirs@ scripts tests man \
@bench_dirs@ support-files @fs_dirs@ @bench_dirs@ support-files @fs_dirs@
......
-----BEGIN CERTIFICATE-----
MIIDaDCCAtGgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTU0MzE4WhcNMDIwNjI0
MTU0MzE4WjCBhTELMAkGA1UEBhMCRkkxEzARBgNVBAgTClNvbWUtU3RhdGUxETAP
BgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQKExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYD
VQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9udUBteXNxbC5jb20w
gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJz9FCvWX8c+Xr6mxzfZvPainIPT
ODNsQ0f2kAs0epP+peUn4LHxLybp2dkUHTtJLXyUyk7cXfnUd+0fRazK2/Vz48bZ
swGwg9Rhg3P02Ku+CMWYulHzN6uVRzfrDUSkDoky2DGL3A6B8P4JRc2qcr+kjhh5
6r1VJlXs9N3DqeEdAgMBAAGjgeUwgeIwHQYDVR0OBBYEFKUK1nK13+TCK3sHXtNN
Ugfhg2t/MIGyBgNVHSMEgaowgaeAFKUK1nK13+TCK3sHXtNNUgfhg2t/oYGLpIGI
MIGFMQswCQYDVQQGEwJGSTETMBEGA1UECBMKU29tZS1TdGF0ZTERMA8GA1UEBxMI
SGVsc2lua2kxGTAXBgNVBAoTEE15U1FMIEZpbmxhbmQgQUIxFDASBgNVBAMTC1Rv
bnUgU2FtdWVsMR0wGwYJKoZIhvcNAQkBFg50b251QG15c3FsLmNvbYIBADAMBgNV
HRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4GBAI+YJKoa+IP3WYr8iLcVk5j7lZ9D
GS8reuALafnE7VX1xMlXP5EnJjT7YYYmtiB2tYj7+eQ+ajRXWWyY5NtO5ob+dm8z
OBX43v08C5vNSAFpwZWTutzb0nSd8kOABGJ04MBDJZk8QNkTfU6C7c3ZJ/gW8Guv
I+cxfz6oCYEfKLBN
-----END CERTIFICATE-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
Validity
Not Before: Jun 24 16:03:20 2001 GMT
Not After : Jun 24 16:03:20 2002 GMT
Subject: C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@mysql.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:e8:d4:52:cd:4e:bb:96:16:3a:f0:89:6b:90:4c:
db:e0:30:75:5a:02:72:62:bf:ed:da:be:09:e8:80:
db:80:54:30:d6:75:ed:e3:10:a5:15:44:5b:29:91:
12:fe:0c:b7:76:4d:e9:5f:56:5c:45:3c:ad:b2:71:
2d:6a:7a:cb:bc:04:80:08:74:d6:7d:f6:7c:5c:76:
db:35:c4:f6:f5:d8:d4:89:9f:9d:cc:3f:4e:3f:73:
c1:3e:41:7e:4e:09:bf:ea:1a:d9:a2:13:0d:d1:0c:
da:d8:f4:9b:b8:54:21:17:ae:d7:b3:02:61:87:a9:
01:ff:f4:fe:9c:7a:fc:67:43
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
BC:FB:BB:8F:C4:85:BA:5F:A8:F2:C3:3D:C9:0F:DB:16:E7:13:BC:B2
X509v3 Authority Key Identifier:
keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
serial:00
Signature Algorithm: md5WithRSAEncryption
1c:e0:87:2c:2f:b3:a4:39:44:7f:96:7b:2f:c9:1f:91:84:0b:
9f:d0:0a:f8:40:70:d0:dd:bd:91:0a:c6:d5:ac:8f:51:77:9c:
35:28:e8:b6:5f:57:9e:5c:b5:9b:ae:5d:3d:7c:05:45:2e:89:
3a:03:e1:f2:00:cb:c1:ed:3e:48:3b:5f:4e:50:d2:b4:a5:36:
0f:1a:dc:79:49:1e:03:2f:27:c1:e4:62:d6:ef:3f:ab:2e:ab:
dd:e5:bc:cb:20:a3:dd:ab:81:69:26:9c:03:42:1b:4c:b7:aa:
57:6d:2a:de:c0:5e:6e:74:d0:83:90:ec:ad:bb:ba:f0:cc:cf:
41:3d
-----BEGIN CERTIFICATE-----
MIIDoTCCAwqgAwIBAgIBAzANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTYwMzIwWhcNMDIwNjI0
MTYwMzIwWjCBkTELMAkGA1UEBhMCRUUxEzARBgNVBAgTClNvbWUtU3RhdGUxEDAO
BgNVBAcTB1RhbGxpbm4xJjAkBgNVBAoTHU15U1FMIGRlbW8gY2xpZW50IGNlcnRp
ZmljYXRlMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9u
dUBteXNxbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOjUUs1Ou5YW
OvCJa5BM2+AwdVoCcmK/7dq+CeiA24BUMNZ17eMQpRVEWymREv4Mt3ZN6V9WXEU8
rbJxLWp6y7wEgAh01n32fFx22zXE9vXY1Imfncw/Tj9zwT5Bfk4Jv+oa2aITDdEM
2tj0m7hUIReu17MCYYepAf/0/px6/GdDAgMBAAGjggERMIIBDTAJBgNVHRMEAjAA
MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
BgNVHQ4EFgQUvPu7j8SFul+o8sM9yQ/bFucTvLIwgbIGA1UdIwSBqjCBp4AUpQrW
crXf5MIrewde001SB+GDa3+hgYukgYgwgYUxCzAJBgNVBAYTAkZJMRMwEQYDVQQI
EwpTb21lLVN0YXRlMREwDwYDVQQHEwhIZWxzaW5raTEZMBcGA1UEChMQTXlTUUwg
RmlubGFuZCBBQjEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
DnRvbnVAbXlzcWwuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBABzghywvs6Q5RH+W
ey/JH5GEC5/QCvhAcNDdvZEKxtWsj1F3nDUo6LZfV55ctZuuXT18BUUuiToD4fIA
y8HtPkg7X05Q0rSlNg8a3HlJHgMvJ8HkYtbvP6suq93lvMsgo92rgWkmnANCG0y3
qldtKt7AXm500IOQ7K27uvDMz0E9
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,8CE2AB38FB50D4B9
rrnYZLUKlzV4U7+wqe5CWzTd4RLJb5h4M77aBRQfuHGejSaRsskN2ffpO8uQEAYM
WTJSRC+NO+jDMBZhzt1ktWqCs8d6l6azHoBybIrMJsbUhwybm+OiOfp23RrbNoS/
S4fsgNdAAGhsRvKDdsItCyYvdH8nTzn+g9r/z2V4tOOXd6MYuT42XA6Uz2tis2SZ
GWEGa7mAweApzSiibE+pzjPS+fdX4E12n6NCVYLhn1JuvzVva/KFSebs4Wh75miC
WvRgkt/5eDQn+vkV67hE3I6p9pPcLh1+PMfaQ25U8VM/r7ejnVFWm7teGH6GKPKJ
cU+PYfblyWcgtiO/fwfGMIqSyNtHj/C3VFVie5D1MTJzBopiPGEcfz00LjBccjjh
j1meTRVN8pMZTgkxlnIFwbU6TPPvx8a9urFVQIJ4z8r2EMvYh5Cqpq87+lH9Pn0C
vzCl78Tz5QLghXNnMbbdD2aPP0PwPEXgh86iZxo06g85n0l26WUzYJlWzBYD4DrF
SbnEUAftTujEOm6MqJNLpJN6UPOtq/HvSaHl1bykGK+zU4gqHj0ur03HlF0l4xNg
OfsoNsJV+O9RUUJ0+D5eqUALJjN8TCV1wNMXOVzr/ue3QCVdlWVfZY4RPffwK9Yp
Fh52T7a2v+shhqZUQNtFDAg50Ac7deUthSWNmi5N680POnJg9KdtBdMhYLa1j3rP
D9oasSK0ugevHuQ6wUiD/95CzZlJXE9K4kTTYmaRk5MTWXhFQxdqHZo1v+pGtaNI
f+/E7q7BiNesSt31U/vkX0Tm3oJ1dgOnS8M2uxiYiKH2mJ/E32tZKw==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAkVFMRMwEQYDVQQIEwpTb21lLVN0YXRl
MRAwDgYDVQQHEwdUYWxsaW5uMSYwJAYDVQQKEx1NeVNRTCBkZW1vIGNsaWVudCBj
ZXJ0aWZpY2F0ZTEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
DnRvbnVAbXlzcWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDo1FLN
TruWFjrwiWuQTNvgMHVaAnJiv+3avgnogNuAVDDWde3jEKUVRFspkRL+DLd2Telf
VlxFPK2ycS1qesu8BIAIdNZ99nxcdts1xPb12NSJn53MP04/c8E+QX5OCb/qGtmi
Ew3RDNrY9Ju4VCEXrtezAmGHqQH/9P6cevxnQwIDAQABoAAwDQYJKoZIhvcNAQEE
BQADgYEAvENK1JAQfC8xnrFGw2IxfUmUwlRidiRtYTgtVfTr7vA+m4WaaKioni6E
PQXjcvl6kfyRoxc4qWsGi3T7QM2RnvCtbwR2NGSIKX1cBTS31RMr12NSAeXn6Twz
ZwSZ55EHj9N2hArTPNlVjxvDQX3D6/ZBi6JnHAxXigzDqhArgjU=
-----END CERTIFICATE REQUEST-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 2 (0x2)
Signature Algorithm: md5WithRSAEncryption
Issuer: C=FI, ST=Some-State, L=Helsinki, O=MySQL Finland AB, CN=Tonu Samuel/Email=tonu@mysql.com
Validity
Not Before: Jun 24 16:02:28 2001 GMT
Not After : Jun 24 16:02:28 2002 GMT
Subject: C=EE, ST=Some-State, L=Tallinn, O=MySQL server demo certificate, CN=Tonu Samuel/Email=tonu@mysql.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (1024 bit)
Modulus (1024 bit):
00:9e:ac:8d:d8:1d:9c:b2:fd:88:96:2c:ba:42:53:
fa:5d:bd:85:8a:e5:ca:d3:0f:c0:01:3c:f2:92:46:
4f:d9:80:ae:2a:89:cf:ef:e8:d4:65:fc:f6:f5:3a:
26:4c:29:db:06:fa:34:a1:87:f3:97:b5:3c:94:f1:
84:05:ac:ad:57:25:d9:02:db:00:71:e0:a9:aa:b4:
1d:29:36:5e:a9:a4:0d:f2:45:b9:83:74:2b:45:f3:
e2:23:bc:e7:5c:e6:11:b6:f6:dd:c4:ac:ed:65:42:
2c:39:47:2a:c9:eb:5f:45:03:10:ab:23:bc:ca:5c:
82:9a:b7:b3:6d:67:18:d2:c7
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
Netscape Comment:
OpenSSL Generated Certificate
X509v3 Subject Key Identifier:
94:68:BF:DA:F6:E2:09:EF:3A:C8:27:AE:D7:B7:02:F0:DC:4B:C1:3B
X509v3 Authority Key Identifier:
keyid:A5:0A:D6:72:B5:DF:E4:C2:2B:7B:07:5E:D3:4D:52:07:E1:83:6B:7F
DirName:/C=FI/ST=Some-State/L=Helsinki/O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@mysql.com
serial:00
Signature Algorithm: md5WithRSAEncryption
8c:1a:90:70:f6:1a:70:0e:c9:28:93:74:e2:2b:b8:2a:d0:ce:
40:15:e8:af:44:f8:89:16:20:f5:c2:b9:ed:aa:4e:3c:40:e2:
9c:62:aa:48:98:ac:17:84:ef:35:72:59:43:09:35:17:c5:9a:
3e:3d:ef:97:bf:57:f2:2a:f6:56:5d:a4:7c:68:58:b9:d6:9b:
0f:57:0e:55:22:17:b0:b7:77:27:4f:da:b3:88:c1:6d:d6:8f:
31:ec:0d:a2:25:60:66:2f:0f:86:8a:d6:08:b8:71:b1:b5:70:
60:04:56:96:ff:bd:5e:ed:94:bc:44:bd:24:e0:2f:90:e5:23:
51:4e
-----BEGIN CERTIFICATE-----
MIIDoTCCAwqgAwIBAgIBAjANBgkqhkiG9w0BAQQFADCBhTELMAkGA1UEBhMCRkkx
EzARBgNVBAgTClNvbWUtU3RhdGUxETAPBgNVBAcTCEhlbHNpbmtpMRkwFwYDVQQK
ExBNeVNRTCBGaW5sYW5kIEFCMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqG
SIb3DQEJARYOdG9udUBteXNxbC5jb20wHhcNMDEwNjI0MTYwMjI4WhcNMDIwNjI0
MTYwMjI4WjCBkTELMAkGA1UEBhMCRUUxEzARBgNVBAgTClNvbWUtU3RhdGUxEDAO
BgNVBAcTB1RhbGxpbm4xJjAkBgNVBAoTHU15U1FMIHNlcnZlciBkZW1vIGNlcnRp
ZmljYXRlMRQwEgYDVQQDEwtUb251IFNhbXVlbDEdMBsGCSqGSIb3DQEJARYOdG9u
dUBteXNxbC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ6sjdgdnLL9
iJYsukJT+l29hYrlytMPwAE88pJGT9mAriqJz+/o1GX89vU6Jkwp2wb6NKGH85e1
PJTxhAWsrVcl2QLbAHHgqaq0HSk2XqmkDfJFuYN0K0Xz4iO851zmEbb23cSs7WVC
LDlHKsnrX0UDEKsjvMpcgpq3s21nGNLHAgMBAAGjggERMIIBDTAJBgNVHRMEAjAA
MCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
BgNVHQ4EFgQUlGi/2vbiCe86yCeu17cC8NxLwTswgbIGA1UdIwSBqjCBp4AUpQrW
crXf5MIrewde001SB+GDa3+hgYukgYgwgYUxCzAJBgNVBAYTAkZJMRMwEQYDVQQI
EwpTb21lLVN0YXRlMREwDwYDVQQHEwhIZWxzaW5raTEZMBcGA1UEChMQTXlTUUwg
RmlubGFuZCBBQjEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
DnRvbnVAbXlzcWwuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIwakHD2GnAOySiT
dOIruCrQzkAV6K9E+IkWIPXCue2qTjxA4pxiqkiYrBeE7zVyWUMJNRfFmj4975e/
V/Iq9lZdpHxoWLnWmw9XDlUiF7C3dydP2rOIwW3WjzHsDaIlYGYvD4aK1gi4cbG1
cGAEVpb/vV7tlLxEvSTgL5DlI1FO
-----END CERTIFICATE-----
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,6CBD09E71246DC01
byRzq5+j3r8FX2kQerTUZT5Bw/N6zrN3cmH6NHGJcrqD+vcPdtWf+Rk+mpNXgSQn
ldkfmniU/htzJ0cUV+KE229Qx10Hx9mIJIbf0Y/rBCUBuaXWVrQB36W9w3rkNPFA
EEuRMkreOJF42RD16+NBJv+RcHIGzGejXecJKUGF5DKlN0U8YHXnkXTQl54kIdr0
H7rTrvJygwPk9/ik0M9/vmwduAMvTaHDmvgeolpMlJkxwz8vYkbUnFFJZhB6XNCb
1w3lJ0EmRJicK5BnZmCEmgt8xiv0PAtg00jBbwddQbn1reAyViBtBT9iXdusHXS5
Po63rSt7r3MO8aetcMQ6FkklH+ChuS/vFoNY57AwrzF4uEI4GSoZP0ESrRC5Ar5W
Lzg/HrQAWbPCRlb6Jj3db1woRzFS8joOashROsZdeV/5P4Emhc6J7QMTvB1OHAhQ
ugOJazJtxjg0DN8+9cM1wtHI7N89PLHhOg13LZNLeeehzIlPwKI2JLqXUc6oR407
i+S7GCqu7wU+if0Enux8Dj7yrvnTUiqVCL2dyKTS3sBq0Cm2UhbecHclor13y6no
y1o50TKKD6Zig2hZmSpqKznMxGMVIT36BE0aOMQUmk+aVnRuROclwTTL0ZNLzA+g
QRTRfQ6iNMf34ypqAMdAMPzDGLPycKuFdxVQxFEVaM2/mrdWFwVAqFsLvzyGvdrh
nkNyRgTWR/pfH9b3mXLqf6gMPNs764WhFIcZIDk9a4XBBUm2YDb2CxDzDCo/EUMA
jvIiU0Jt132SEHHF/wAka6d2DnwZ3vexRp6Tebv/uy9IlMLPE+68dw==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE REQUEST-----
MIIB0jCCATsCAQAwgZExCzAJBgNVBAYTAkVFMRMwEQYDVQQIEwpTb21lLVN0YXRl
MRAwDgYDVQQHEwdUYWxsaW5uMSYwJAYDVQQKEx1NeVNRTCBzZXJ2ZXIgZGVtbyBj
ZXJ0aWZpY2F0ZTEUMBIGA1UEAxMLVG9udSBTYW11ZWwxHTAbBgkqhkiG9w0BCQEW
DnRvbnVAbXlzcWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCerI3Y
HZyy/YiWLLpCU/pdvYWK5crTD8ABPPKSRk/ZgK4qic/v6NRl/Pb1OiZMKdsG+jSh
h/OXtTyU8YQFrK1XJdkC2wBx4KmqtB0pNl6ppA3yRbmDdCtF8+IjvOdc5hG29t3E
rO1lQiw5RyrJ619FAxCrI7zKXIKat7NtZxjSxwIDAQABoAAwDQYJKoZIhvcNAQEE
BQADgYEAlrUnGX4LYIiVjztHA4gUcOSVeEHCci2qEUq+7yY1JhAw54YDa2MLTTwa
cH+rXLHjN0MTNfv9tRxdSX+trk3pyvhgFjssD100dJkF83RfVv2tKg9kscVOGQp7
MkwOnJjfAjQBlTbTOQM46BTjv2FgvsppkO3ViryI//YxKvj/628=
-----END CERTIFICATE REQUEST-----
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# This file is public domain and comes with NO WARRANTY of any kind # This file is public domain and comes with NO WARRANTY of any kind
INCLUDES = -I$(srcdir)/../include \ INCLUDES = -I$(srcdir)/../include $(openssl_includes) \
-I../include -I$(srcdir)/.. -I$(top_srcdir) \ -I../include -I$(srcdir)/.. -I$(top_srcdir) \
-I.. -I..
LIBS = @CLIENT_LIBS@ LIBS = @CLIENT_LIBS@
......
...@@ -2010,7 +2010,7 @@ then ...@@ -2010,7 +2010,7 @@ then
AC_SUBST(THREAD_LPROGRAMS) AC_SUBST(THREAD_LPROGRAMS)
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o" THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o"
AC_SUBST(THREAD_LOBJECTS) AC_SUBST(THREAD_LOBJECTS)
sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap sql" sql_server_dirs="strings dbug mysys extra regex isam merge myisam myisammrg heap vio sql"
server_scripts="mysqld_safe mysql_install_db" server_scripts="mysqld_safe mysql_install_db"
if test X"$have_berkeley_db" != Xno; then if test X"$have_berkeley_db" != Xno; then
if test X"$have_berkeley_db" != Xyes; then if test X"$have_berkeley_db" != Xyes; then
......
...@@ -189,7 +189,13 @@ ...@@ -189,7 +189,13 @@
# endif # endif
#endif /* TIME_WITH_SYS_TIME */ #endif /* TIME_WITH_SYS_TIME */
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
#ifdef HAVE_OPENSSL
#define crypt dummy
#endif
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_OPENSSL
#undef crypt
#endif
#endif #endif
#if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA) #if defined(__cplusplus) && defined(NO_CPLUSPLUS_ALLOCA)
#undef HAVE_ALLOCA #undef HAVE_ALLOCA
......
...@@ -137,11 +137,9 @@ my_bool vio_poll_read(Vio *vio,uint timeout); ...@@ -137,11 +137,9 @@ my_bool vio_poll_read(Vio *vio,uint timeout);
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
#include <openssl/x509.h> #define HEADER_DES_LOCL_H dummy_something
#include <openssl/ssl.h> #include <openssl/ssl.h>
#include <openssl/err.h> #include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/asn1.h>
#include "my_net.h" /* needed because of struct in_addr */ #include "my_net.h" /* needed because of struct in_addr */
...@@ -184,10 +182,9 @@ struct st_VioSSLAcceptorFd ...@@ -184,10 +182,9 @@ struct st_VioSSLAcceptorFd
state_connect = 1, state_connect = 1,
state_accept = 2 state_accept = 2
}; };
BIO* bio_; // BIO* bio_;
char *ssl_cip_; // char desc_[100];
char desc_[100]; // Vio* sd_;
Vio* sd_;
/* function pointers which are only once for SSL server /* function pointers which are only once for SSL server
Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */ Vio*(*sslaccept)(struct st_VioSSLAcceptorFd*,Vio*); */
...@@ -200,8 +197,8 @@ struct st_VioSSLConnectorFd ...@@ -200,8 +197,8 @@ struct st_VioSSLConnectorFd
SSL_METHOD* ssl_method_; SSL_METHOD* ssl_method_;
/* function pointers which are only once for SSL client */ /* function pointers which are only once for SSL client */
}; };
Vio *sslaccept(struct st_VioSSLAcceptorFd*, Vio*); void sslaccept(struct st_VioSSLAcceptorFd*, Vio*);
Vio *sslconnect(struct st_VioSSLConnectorFd*, Vio*); void sslconnect(struct st_VioSSLConnectorFd*, Vio*);
#else /* HAVE_OPENSSL */ #else /* HAVE_OPENSSL */
/* This dummy is required to maintain proper size of st_mysql in mysql.h */ /* This dummy is required to maintain proper size of st_mysql in mysql.h */
...@@ -250,6 +247,7 @@ struct st_vio ...@@ -250,6 +247,7 @@ struct st_vio
BIO* bio_; BIO* bio_;
SSL* ssl_; SSL* ssl_;
my_bool open_; my_bool open_;
char *ssl_cip_;
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
#endif /* HAVE_VIO */ #endif /* HAVE_VIO */
}; };
......
...@@ -25,6 +25,7 @@ extern char* srv_arch_dir; ...@@ -25,6 +25,7 @@ extern char* srv_arch_dir;
extern ulint srv_n_data_files; extern ulint srv_n_data_files;
extern char** srv_data_file_names; extern char** srv_data_file_names;
extern ulint* srv_data_file_sizes; extern ulint* srv_data_file_sizes;
extern ulint* srv_data_file_is_raw_partition;
extern char** srv_log_group_home_dirs; extern char** srv_log_group_home_dirs;
...@@ -103,13 +104,26 @@ typedef struct srv_sys_struct srv_sys_t; ...@@ -103,13 +104,26 @@ typedef struct srv_sys_struct srv_sys_t;
/* The server system */ /* The server system */
extern srv_sys_t* srv_sys; extern srv_sys_t* srv_sys;
/* Alternatives for fiel flush option in Unix; see the InnoDB manual about /* Alternatives for file flush option in Unix; see the InnoDB manual about
what these mean */ what these mean */
#define SRV_UNIX_FDATASYNC 1 #define SRV_UNIX_FDATASYNC 1
#define SRV_UNIX_O_DSYNC 2 #define SRV_UNIX_O_DSYNC 2
#define SRV_UNIX_LITTLESYNC 3 #define SRV_UNIX_LITTLESYNC 3
#define SRV_UNIX_NOSYNC 4 #define SRV_UNIX_NOSYNC 4
/* Raw partition flags */
#define SRV_OLD_RAW 1
#define SRV_NEW_RAW 2
void
srv_mysql_thread_release(void);
/*==========================*/
os_event_t
srv_mysql_thread_event_get(void);
void
srv_mysql_thread_slot_free(
/*==========================*/
os_event_t event);
/************************************************************************* /*************************************************************************
Boots Innobase server. */ Boots Innobase server. */
......
...@@ -2537,7 +2537,10 @@ row_search_for_mysql( ...@@ -2537,7 +2537,10 @@ row_search_for_mysql(
unique_search_from_clust_index = TRUE; unique_search_from_clust_index = TRUE;
if (trx->mysql_n_tables_locked == 0 /* Disable this optimization (hence FALSE below) until
the hang of Peter Zaitsev has been tracked down */
if (FALSE && trx->mysql_n_tables_locked == 0
&& !prebuilt->sql_stat_start) { && !prebuilt->sql_stat_start) {
/* This is a SELECT query done as a consistent read, /* This is a SELECT query done as a consistent read,
......
...@@ -64,6 +64,8 @@ ulint srv_n_data_files = 0; ...@@ -64,6 +64,8 @@ ulint srv_n_data_files = 0;
char** srv_data_file_names = NULL; char** srv_data_file_names = NULL;
ulint* srv_data_file_sizes = NULL; /* size in database pages */ ulint* srv_data_file_sizes = NULL; /* size in database pages */
ulint* srv_data_file_is_raw_partition = NULL;
char** srv_log_group_home_dirs = NULL; char** srv_log_group_home_dirs = NULL;
ulint srv_n_log_groups = ULINT_MAX; ulint srv_n_log_groups = ULINT_MAX;
...@@ -1490,6 +1492,7 @@ srv_init(void) ...@@ -1490,6 +1492,7 @@ srv_init(void)
slot = srv_mysql_table + i; slot = srv_mysql_table + i;
slot->in_use = FALSE; slot->in_use = FALSE;
slot->event = os_event_create(NULL); slot->event = os_event_create(NULL);
slot->suspended = FALSE;
ut_a(slot->event); ut_a(slot->event);
} }
...@@ -1658,6 +1661,7 @@ srv_suspend_mysql_thread( ...@@ -1658,6 +1661,7 @@ srv_suspend_mysql_thread(
slot->thr = thr; slot->thr = thr;
os_event_reset(event); os_event_reset(event);
slot->suspended = TRUE;
slot->suspend_time = ut_time(); slot->suspend_time = ut_time();
...@@ -1689,6 +1693,27 @@ srv_suspend_mysql_thread( ...@@ -1689,6 +1693,27 @@ srv_suspend_mysql_thread(
return(FALSE); return(FALSE);
} }
os_event_t
srv_mysql_thread_event_get(void)
{
srv_slot_t* slot;
os_event_t event;
mutex_enter(&kernel_mutex);
slot = srv_table_reserve_slot_for_mysql();
event = slot->event;
os_event_reset(event);
slot->suspended = TRUE;
mutex_exit(&kernel_mutex);
return(event);
}
/************************************************************************ /************************************************************************
Releases a MySQL OS thread waiting for a lock to be released, if the Releases a MySQL OS thread waiting for a lock to be released, if the
thread is already suspended. */ thread is already suspended. */
...@@ -1712,6 +1737,7 @@ srv_release_mysql_thread_if_suspended( ...@@ -1712,6 +1737,7 @@ srv_release_mysql_thread_if_suspended(
/* Found */ /* Found */
os_event_set(slot->event); os_event_set(slot->event);
slot->suspended = FALSE;
return; return;
} }
...@@ -1720,6 +1746,59 @@ srv_release_mysql_thread_if_suspended( ...@@ -1720,6 +1746,59 @@ srv_release_mysql_thread_if_suspended(
/* not found */ /* not found */
} }
void
srv_mysql_thread_release(void)
/*==========================*/
{
srv_slot_t* slot;
ulint i;
mutex_enter(&kernel_mutex);
for (i = 0; i < OS_THREAD_MAX_N; i++) {
slot = srv_mysql_table + i;
if (slot->in_use && slot->suspended) {
/* Found */
slot->suspended = FALSE;
mutex_exit(&kernel_mutex);
os_event_set(slot->event);
return;
}
}
ut_a(0);
}
void
srv_mysql_thread_slot_free(
/*==========================*/
os_event_t event)
{
srv_slot_t* slot;
ulint i;
mutex_enter(&kernel_mutex);
for (i = 0; i < OS_THREAD_MAX_N; i++) {
slot = srv_mysql_table + i;
if (slot->in_use && slot->event == event) {
/* Found */
slot->in_use = FALSE;
mutex_exit(&kernel_mutex);
return;
}
}
ut_a(0);
}
/************************************************************************* /*************************************************************************
A thread which wakes up threads whose lock wait may have lasted too long. */ A thread which wakes up threads whose lock wait may have lasted too long. */
...@@ -1907,6 +1986,11 @@ srv_master_thread( ...@@ -1907,6 +1986,11 @@ srv_master_thread(
} }
background_loop: background_loop:
/*
sync_array_print_info(sync_primary_wait_array);
os_aio_print();
buf_print_io();
*/
/* In this loop we run background operations while the server /* In this loop we run background operations while the server
is quiet */ is quiet */
...@@ -1967,9 +2051,15 @@ srv_master_thread( ...@@ -1967,9 +2051,15 @@ srv_master_thread(
} }
/* mem_print_new_info(); /* mem_print_new_info();
*/
fsp_print(0); /* fsp_print(0); */
/* fprintf(stderr, "Validating tablespace\n");
fsp_validate(0);
fprintf(stderr, "Validation ok\n");
*/ */
#ifdef UNIV_SEARCH_PERF_STAT #ifdef UNIV_SEARCH_PERF_STAT
/* btr_search_print_info(); */ /* btr_search_print_info(); */
#endif #endif
......
...@@ -330,10 +330,28 @@ open_or_create_data_files( ...@@ -330,10 +330,28 @@ open_or_create_data_files(
sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]); sprintf(name, "%s%s", srv_data_home, srv_data_file_names[i]);
files[i] = os_file_create(name, OS_FILE_CREATE, if (srv_data_file_is_raw_partition[i] == 0) {
files[i] = os_file_create(name, OS_FILE_CREATE,
OS_FILE_NORMAL, &ret); OS_FILE_NORMAL, &ret);
} else if (srv_data_file_is_raw_partition[i] == SRV_OLD_RAW) {
ret = FALSE;
} else if (srv_data_file_is_raw_partition[i] == SRV_NEW_RAW) {
files[i] = os_file_create(
name, OS_FILE_OPEN, OS_FILE_NORMAL, &ret);
if (!ret) {
fprintf(stderr,
"InnoDB: Error in opening %s\n", name);
return(DB_ERROR);
}
}
if (ret == FALSE) { if (ret == FALSE) {
if (os_file_get_last_error() != if (srv_data_file_is_raw_partition[i] == 0
&& os_file_get_last_error() !=
OS_FILE_ALREADY_EXISTS) { OS_FILE_ALREADY_EXISTS) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error in creating or opening %s\n", "InnoDB: Error in creating or opening %s\n",
...@@ -364,8 +382,10 @@ open_or_create_data_files( ...@@ -364,8 +382,10 @@ open_or_create_data_files(
ret = os_file_get_size(files[i], &size, &size_high); ret = os_file_get_size(files[i], &size, &size_high);
ut_a(ret); ut_a(ret);
if (size != UNIV_PAGE_SIZE * srv_data_file_sizes[i] if (srv_data_file_is_raw_partition[i] == 0
|| size_high != 0) { && (size != UNIV_PAGE_SIZE * srv_data_file_sizes[i]
|| size_high != 0)) {
fprintf(stderr, fprintf(stderr,
"InnoDB: Error: data file %s is of different size\n" "InnoDB: Error: data file %s is of different size\n"
"InnoDB: than specified in the .cnf file!\n", name); "InnoDB: than specified in the .cnf file!\n", name);
...@@ -722,6 +742,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -722,6 +742,7 @@ innobase_start_or_create_for_mysql(void)
mutex_exit(&(log_sys->mutex)); mutex_exit(&(log_sys->mutex));
} }
/* mutex_create(&row_mysql_thread_mutex); */
sess_sys_init_at_db_start(); sess_sys_init_at_db_start();
if (create_new_db) { if (create_new_db) {
......
...@@ -21,7 +21,7 @@ target = libmysqlclient.la ...@@ -21,7 +21,7 @@ target = libmysqlclient.la
target_defs = -DUNDEF_THREADS_HACK target_defs = -DUNDEF_THREADS_HACK
LIBS = @CLIENT_LIBS@ LIBS = @CLIENT_LIBS@
INCLUDES = -I$(srcdir)/../include -I../include \ INCLUDES = -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
include $(srcdir)/Makefile.shared include $(srcdir)/Makefile.shared
......
...@@ -62,7 +62,7 @@ mysysobjects = $(mysysobjects1) $(mysysobjects2) ...@@ -62,7 +62,7 @@ mysysobjects = $(mysysobjects1) $(mysysobjects2)
target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \ target_libadd = $(mysysobjects) $(mystringsobjects) $(dbugobjects) \
$(vio_objects) $(vio_objects)
target_ldflags = -version-info @SHARED_LIB_VERSION@ target_ldflags = -version-info @SHARED_LIB_VERSION@
vio_objects= vio.lo viosocket.lo vio_objects= vio.lo viosocket.lo viossl.lo viosslfactories.lo
CLEANFILES = $(target_libadd) $(SHLIBOBJS) \ CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
$(target) $(target)
DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \ DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
......
...@@ -1372,7 +1372,7 @@ mysql_ssl_cipher(MYSQL *mysql) ...@@ -1372,7 +1372,7 @@ mysql_ssl_cipher(MYSQL *mysql)
** Free strings in the SSL structure and clear 'use_ssl' flag. ** Free strings in the SSL structure and clear 'use_ssl' flag.
** NB! Errors are not reported until you do mysql_real_connect. ** NB! Errors are not reported until you do mysql_real_connect.
************************************************************************** **************************************************************************
*/
int STDCALL int STDCALL
mysql_ssl_clear(MYSQL *mysql) mysql_ssl_clear(MYSQL *mysql)
{ {
...@@ -1384,11 +1384,11 @@ mysql_ssl_clear(MYSQL *mysql) ...@@ -1384,11 +1384,11 @@ mysql_ssl_clear(MYSQL *mysql)
mysql->options.ssl_cert = 0; mysql->options.ssl_cert = 0;
mysql->options.ssl_ca = 0; mysql->options.ssl_ca = 0;
mysql->options.ssl_capath = 0; mysql->options.ssl_capath = 0;
mysql->options.use_ssl = false; mysql->options.use_ssl = FALSE;
mysql->connector_fd->delete(); my_free(mysql->connector_fd,MYF(MY_ALLOW_ZERO_PTR));
mysql->connector_fd = 0; mysql->connector_fd = 0;
return 0; return 0;
}*/ }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/************************************************************************** /**************************************************************************
...@@ -1781,7 +1781,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user, ...@@ -1781,7 +1781,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
/* Do the SSL layering. */ /* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_));
mysql->net.vio = sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio); sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio);
DBUG_PRINT("info", ("IO layer change done!")); DBUG_PRINT("info", ("IO layer change done!"));
} }
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
...@@ -1984,8 +1984,7 @@ mysql_close(MYSQL *mysql) ...@@ -1984,8 +1984,7 @@ mysql_close(MYSQL *mysql)
bzero((char*) &mysql->options,sizeof(mysql->options)); bzero((char*) &mysql->options,sizeof(mysql->options));
mysql->net.vio = 0; mysql->net.vio = 0;
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
/* ((VioConnectorFd*)(mysql->connector_fd))->delete(); mysql_ssl_clear(mysql);
mysql->connector_fd = 0;*/
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
/* free/close slave list */ /* free/close slave list */
......
...@@ -22,7 +22,7 @@ target_defs = ...@@ -22,7 +22,7 @@ target_defs =
## LIBS = @LIBS@ ## LIBS = @LIBS@
INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \ INCLUDES = @MT_INCLUDES@ -I$(srcdir)/../include -I../include \
-I$(srcdir)/.. -I$(top_srcdir) -I.. -I$(srcdir)/.. -I$(top_srcdir) -I.. $(openssl_includes)
## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include ## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include
include $(top_srcdir)/libmysql/Makefile.shared include $(top_srcdir)/libmysql/Makefile.shared
......
...@@ -68,6 +68,7 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree) ...@@ -68,6 +68,7 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
{ {
FT_WORD *wlist,*p; FT_WORD *wlist,*p;
FT_DOCSTAT docstat; FT_DOCSTAT docstat;
DBUG_ENTER("ft_linearize");
if ((wlist=(FT_WORD *) my_malloc(sizeof(FT_WORD)* if ((wlist=(FT_WORD *) my_malloc(sizeof(FT_WORD)*
(1+wtree->elements_in_tree),MYF(0)))) (1+wtree->elements_in_tree),MYF(0))))
...@@ -85,7 +86,7 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree) ...@@ -85,7 +86,7 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
} }
delete_tree(wtree); delete_tree(wtree);
if (!wlist) if (!wlist)
return NULL; DBUG_RETURN(NULL);
docstat.list->pos=NULL; docstat.list->pos=NULL;
...@@ -109,14 +110,14 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree) ...@@ -109,14 +110,14 @@ FT_WORD * ft_linearize(MI_INFO *info, uint keynr, byte *keybuf, TREE *wtree)
p->weight/=NORM_IN_USE; p->weight/=NORM_IN_USE;
} }
return wlist; DBUG_RETURN(wlist);
} }
#define true_word_char(X) (isalnum(X) || (X)=='_') #define true_word_char(X) (isalnum(X) || (X)=='_')
#ifdef HYPHEN_IS_DELIM #ifdef HYPHEN_IS_DELIM
#define misc_word_char(X) ((X)=='\'') #define misc_word_char(X) ((X)=='\'')
#else #else
#define misc_word_char(X) ((X)=='\'' || (X)=='-') #define misc_word_char(X) ((X)=='\'' || (X)=='-')
#endif #endif
#define word_char(X) (true_word_char(X) || misc_word_char(X)) #define word_char(X) (true_word_char(X) || misc_word_char(X))
......
...@@ -177,14 +177,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf, ...@@ -177,14 +177,7 @@ int _mi_ft_update(MI_INFO *info, uint keynr, byte *keybuf,
(uchar*) old_word->pos,old_word->len, (uchar*) old_word->pos,old_word->len,
(uchar*) new_word->pos,new_word->len,0); (uchar*) new_word->pos,new_word->len,0);
if (cmp==0) if (cmp==0)
{ cmp=sgn(old_word->weight-new_word->weight);
double p=(old_word->weight-new_word->weight)/
(old_word->weight+new_word->weight);
if (p<1e-5)
cmp=0;
else
cmp=sgn(p);
}
else else
cmp=sgn(cmp); cmp=sgn(cmp);
......
...@@ -794,10 +794,10 @@ int _mi_init_bulk_insert(MI_INFO *info) ...@@ -794,10 +794,10 @@ int _mi_init_bulk_insert(MI_INFO *info)
params=(bulk_insert_param *)(info->bulk_insert+share->base.keys); params=(bulk_insert_param *)(info->bulk_insert+share->base.keys);
for (i=0 ; i < share->base.keys ; i++,key++) for (i=0 ; i < share->base.keys ; i++,key++)
{ {
params->info=info;
params->keynr=i;
if (test(key_map & ((ulonglong) 1 << i))) if (test(key_map & ((ulonglong) 1 << i)))
{ {
params->info=info;
params->keynr=i;
init_tree(& info->bulk_insert[i], 0, init_tree(& info->bulk_insert[i], 0,
myisam_bulk_insert_tree_size / num_keys, 0, myisam_bulk_insert_tree_size / num_keys, 0,
(qsort_cmp2)keys_compare, 0, (qsort_cmp2)keys_compare, 0,
......
...@@ -160,7 +160,7 @@ while test $# -gt 0; do ...@@ -160,7 +160,7 @@ while test $# -gt 0; do
SLEEP_TIME=`$ECHO "$1" | $SED -e "s;--sleep=;;"` SLEEP_TIME=`$ECHO "$1" | $SED -e "s;--sleep=;;"`
;; ;;
--mysqld=*) --mysqld=*)
TMP=`$ECHO "$1" | $SED -e "s;--mysqld-=;"` TMP=`$ECHO "$1" | $SED -e "s;--mysqld=;;"`
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $TMP" EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT $TMP"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $TMP" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $TMP"
;; ;;
......
...@@ -11,3 +11,5 @@ payoutID ...@@ -11,3 +11,5 @@ payoutID
19 19
20 20
22 22
Variable_name Value
myisam_bulk_insert_tree_size 8388608
a b
1 a
2 b
3 c
4 d
5 e
6 f
a b
1 a
2 b
3 c
3 c
4 d
5 e
6 f
...@@ -10,3 +10,59 @@ insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1; ...@@ -10,3 +10,59 @@ insert into t2 (payoutID) SELECT DISTINCT payoutID FROM t1;
insert into t2 (payoutID) SELECT payoutID+10 FROM t1; insert into t2 (payoutID) SELECT payoutID+10 FROM t1;
select * from t2; select * from t2;
drop table t1,t2; drop table t1,t2;
#
# bug in bulk insert optimization
# test case by Fournier Jocelyn <joc@presence-pc.com>
#
DROP TABLE IF EXISTS crash1,crash2;
CREATE TABLE `crash1` (
`numeropost` bigint(20) unsigned NOT NULL default '0',
`icone` tinyint(4) unsigned NOT NULL default '0',
`numreponse` bigint(20) unsigned NOT NULL auto_increment,
`contenu` text NOT NULL,
`pseudo` varchar(50) NOT NULL default '',
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`ip` bigint(11) NOT NULL default '0',
`signature` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`numeropost`,`numreponse`)
,KEY `ip` (`ip`),
KEY `date` (`date`),
KEY `pseudo` (`pseudo`),
KEY `numreponse` (`numreponse`)
) TYPE=MyISAM;
CREATE TABLE `crash2` (
`numeropost` bigint(20) unsigned NOT NULL default '0',
`icone` tinyint(4) unsigned NOT NULL default '0',
`numreponse` bigint(20) unsigned NOT NULL auto_increment,
`contenu` text NOT NULL,
`pseudo` varchar(50) NOT NULL default '',
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`ip` bigint(11) NOT NULL default '0',
`signature` tinyint(1) unsigned NOT NULL default '0',
PRIMARY KEY (`numeropost`,`numreponse`),
KEY `ip` (`ip`),
KEY `date` (`date`),
KEY `pseudo` (`pseudo`),
KEY `numreponse` (`numreponse`)
) TYPE=MyISAM;
INSERT INTO crash2
(numeropost,icone,numreponse,contenu,pseudo,date,ip,signature) VALUES
(9,1,56,'test','joce','2001-07-25 13:50:53'
,3649052399,0);
INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
SELECT 1618,icone,contenu,pseudo,date,signature,ip FROM crash2
WHERE numeropost=9 ORDER BY numreponse ASC;
show variables like '%bulk%';
INSERT INTO crash1 (numeropost,icone,contenu,pseudo,date,signature,ip)
SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM crash2
WHERE numeropost=9 ORDER BY numreponse ASC;
DROP TABLE IF EXISTS crash1,crash2;
#
# Test of unions
#
drop table if exists t1,t2;
CREATE TABLE t1 (a int not null, b char (10) not null);
insert into t1 values(1,"a"),(2,"b"),(3,"c");
CREATE TABLE t2 (a int not null, b char (10) not null);
insert into t2 values (3,"c"),(4,"d"),(5,"e"),(6,"f");
select a,b from t1 union select a,b from t2;
select a,b from t1 union all select a,b from t2;
drop table t1,t2;
...@@ -287,6 +287,26 @@ innobase_parse_data_file_paths_and_sizes(void) ...@@ -287,6 +287,26 @@ innobase_parse_data_file_paths_and_sizes(void)
str++; str++;
} }
if (size >= 4096) {
fprintf(stderr,
"InnoDB: error: data file size must not be >= 4096M\n");
return(FALSE);
}
if (strlen(str) >= 6
&& *str == 'n'
&& *(str + 1) == 'e'
&& *(str + 2) == 'w') {
str += 3;
}
if (strlen(str) >= 3
&& *str == 'r'
&& *(str + 1) == 'a'
&& *(str + 2) == 'w') {
str += 3;
}
if (size == 0) { if (size == 0) {
return(FALSE); return(FALSE);
} }
...@@ -301,8 +321,9 @@ innobase_parse_data_file_paths_and_sizes(void) ...@@ -301,8 +321,9 @@ innobase_parse_data_file_paths_and_sizes(void)
} }
} }
srv_data_file_names = (char**) ut_malloc(i * sizeof(void*)); srv_data_file_names = (char**)ut_malloc(i * sizeof(void*));
srv_data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint)); srv_data_file_sizes = (ulint*)ut_malloc(i * sizeof(ulint));
srv_data_file_is_raw_partition = (ulint*)ut_malloc(i * sizeof(ulint));
srv_n_data_files = i; srv_n_data_files = i;
...@@ -337,6 +358,27 @@ innobase_parse_data_file_paths_and_sizes(void) ...@@ -337,6 +358,27 @@ innobase_parse_data_file_paths_and_sizes(void)
str++; str++;
} }
srv_data_file_is_raw_partition[i] = 0;
if (strlen(str) >= 6
&& *str == 'n'
&& *(str + 1) == 'e'
&& *(str + 2) == 'w') {
str += 3;
srv_data_file_is_raw_partition[i] = SRV_NEW_RAW;
}
if (strlen(str) >= 3
&& *str == 'r'
&& *(str + 1) == 'a'
&& *(str + 2) == 'w') {
str += 3;
if (srv_data_file_is_raw_partition[i] == 0) {
srv_data_file_is_raw_partition[i] = SRV_OLD_RAW;
}
}
srv_data_file_names[i] = path; srv_data_file_names[i] = path;
srv_data_file_sizes[i] = size; srv_data_file_sizes[i] = size;
...@@ -464,6 +506,7 @@ innobase_init(void) ...@@ -464,6 +506,7 @@ innobase_init(void)
ret = innobase_parse_data_file_paths_and_sizes(); ret = innobase_parse_data_file_paths_and_sizes();
if (ret == FALSE) { if (ret == FALSE) {
fprintf(stderr, "InnoDB: syntax error in innodb_data_file_path\n");
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
......
...@@ -693,6 +693,28 @@ void clean_up(bool print_message) ...@@ -693,6 +693,28 @@ void clean_up(bool print_message)
#ifdef USE_RAID #ifdef USE_RAID
end_raid(); end_raid();
#endif #endif
#ifdef HAVE_OPENSSL
if(opt_ssl_key) {
my_free(opt_ssl_key,MYF(0));
opt_ssl_key=0;
}
if(opt_ssl_cert) {
my_free(opt_ssl_cert,MYF(0));
opt_ssl_cert=0;
}
if(opt_ssl_ca) {
my_free(opt_ssl_ca,MYF(0));
opt_ssl_ca=0;
}
if(opt_ssl_capath) {
my_free(opt_ssl_capath,MYF(0));
opt_ssl_capath=0;
}
if(ssl_acceptor_fd) {
my_free((gptr)ssl_acceptor_fd,MYF(0));
ssl_acceptor_fd=0;
}
#endif /* HAVE_OPENSSL */
free_defaults(defaults_argv); free_defaults(defaults_argv);
my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR));
my_free(mysql_tmpdir,MYF(0)); my_free(mysql_tmpdir,MYF(0));
......
...@@ -1239,12 +1239,12 @@ select_insert::prepare(List<Item> &values) ...@@ -1239,12 +1239,12 @@ select_insert::prepare(List<Item> &values)
table->next_number_field=table->found_next_number_field; table->next_number_field=table->found_next_number_field;
thd->count_cuted_fields=1; /* calc cuted fields */ thd->count_cuted_fields=1; /* calc cuted fields */
thd->cuted_fields=0; thd->cuted_fields=0;
if (info.handle_duplicates != DUP_REPLACE) if (info.handle_duplicates != DUP_REPLACE)
table->file->extra(HA_EXTRA_WRITE_CACHE); table->file->extra(HA_EXTRA_WRITE_CACHE);
if (info.handle_duplicates == DUP_IGNORE || if (info.handle_duplicates == DUP_IGNORE ||
info.handle_duplicates == DUP_REPLACE) info.handle_duplicates == DUP_REPLACE)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
table->file->deactivate_non_unique_index((ha_rows) 0); table->file->deactivate_non_unique_index((ha_rows) 0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -425,7 +425,7 @@ check_connections(THD *thd) ...@@ -425,7 +425,7 @@ check_connections(THD *thd)
DBUG_PRINT("info", ("Agreed to change IO layer to SSL") ); DBUG_PRINT("info", ("Agreed to change IO layer to SSL") );
/* Do the SSL layering. */ /* Do the SSL layering. */
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
net->vio = sslaccept(ssl_acceptor_fd, net->vio); sslaccept(ssl_acceptor_fd, net->vio);
DBUG_PRINT("info", ("Reading user information over SSL layer")); DBUG_PRINT("info", ("Reading user information over SSL layer"));
if ((pkt_len=my_net_read(net)) == packet_error || if ((pkt_len=my_net_read(net)) == packet_error ||
pkt_len < NORMAL_HANDSHAKE_SIZE) pkt_len < NORMAL_HANDSHAKE_SIZE)
...@@ -2426,7 +2426,7 @@ mysql_init_query(THD *thd) ...@@ -2426,7 +2426,7 @@ mysql_init_query(THD *thd)
thd->lex.select_lex.item_list.empty(); thd->lex.select_lex.item_list.empty();
thd->lex.value_list.empty(); thd->lex.value_list.empty();
thd->lex.select_lex.table_list.elements=0; thd->lex.select_lex.table_list.elements=0;
thd->free_list=0; thd->free_list=0; thd->lex.union_option=0;
thd->lex.select = &thd->lex.select_lex; thd->lex.select = &thd->lex.select_lex;
thd->lex.select_lex.table_list.first=0; thd->lex.select_lex.table_list.first=0;
thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first; thd->lex.select_lex.table_list.next= (byte**) &thd->lex.select_lex.table_list.first;
...@@ -2444,7 +2444,7 @@ mysql_init_select(LEX *lex) ...@@ -2444,7 +2444,7 @@ mysql_init_select(LEX *lex)
select_lex->select_limit=current_thd->default_select_limit; select_lex->select_limit=current_thd->default_select_limit;
select_lex->offset_limit=0; select_lex->offset_limit=0;
select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE; select_lex->options=0; select_lex->linkage=UNSPECIFIED_TYPE;
select_lex->select_number = 0; lex->exchange = 0; lex->union_option=0; select_lex->select_number = 0; lex->exchange = 0;
lex->proc_list.first=0; lex->proc_list.first=0;
select_lex->order_list.elements=select_lex->group_list.elements=0; select_lex->order_list.elements=select_lex->group_list.elements=0;
select_lex->order_list.first=0; select_lex->order_list.first=0;
......
...@@ -21,104 +21,66 @@ ...@@ -21,104 +21,66 @@
#include "mysql_priv.h" #include "mysql_priv.h"
#include "sql_select.h"
/* Union of selects */ /* Union of selects */
int mysql_union(THD *thd,LEX *lex,uint no_of_selects) int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
{ {
SELECT_LEX *sl, *for_order=&lex->select_lex; uint no=0; int res=0; SELECT_LEX *sl, *for_order=&lex->select_lex; int res=0;
select_create *create_result; TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL;
List<Item> fields; TABLE *table=(TABLE *)NULL; TABLE_LIST *resulting=(TABLE_LIST *)NULL;
for (;for_order->next;for_order=for_order->next); for (;for_order->next;for_order=for_order->next);
ORDER *some_order = (ORDER *)for_order->order_list.first; ORDER *some_order = (ORDER *)for_order->order_list.first;
for (sl=&lex->select_lex;sl;sl=sl->next, no++) List<Item> list;
List_iterator<Item> it(lex->select_lex.item_list);
Item *item;
TABLE_LIST *s=(TABLE_LIST*) lex->select_lex.table_list.first;
while ((item= it++))
if (list.push_back(item))
return -1;
if (setup_fields(thd,s,list,0,0))
return -1;
TMP_TABLE_PARAM *tmp_table_param= new TMP_TABLE_PARAM;
count_field_types(tmp_table_param,list,0);
tmp_table_param->end_write_records= HA_POS_ERROR; tmp_table_param->copy_field=0;
tmp_table_param->copy_field_count=tmp_table_param->field_count=
tmp_table_param->sum_func_count= tmp_table_param->func_count=0;
if (!(table=create_tmp_table(thd, tmp_table_param, list, (ORDER*) 0, !lex->union_option,
0, 0, lex->select_lex.options | thd->options)))
return 1;
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
return 1;
resulting->db=s->db ? s->db : thd->db;
resulting->real_name=table->real_name;
resulting->name=table->table_name;
resulting->table=table;
for (sl=&lex->select_lex;sl;sl=sl->next)
{ {
TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first; TABLE_LIST *tables=(TABLE_LIST*) sl->table_list.first;
if (!no) // First we do CREATE from SELECT select_insert *result;
{ if ((result=new select_insert(table,&list, DUP_IGNORE, true)))
lex->create_info.options=HA_LEX_CREATE_TMP_TABLE; {
lex->create_info.db_type=DB_TYPE_MYISAM; res=mysql_select(thd,tables,sl->item_list,
lex->create_info.row_type = ROW_TYPE_DEFAULT; sl->where,
lex->create_info.avg_row_length = 0; sl->ftfunc_list,
lex->create_info.max_rows=INT_MAX; lex->create_info.min_rows=0; (ORDER*) some_order,
lex->create_info.comment=lex->create_info.password=NullS; (ORDER*) sl->group_list.first,
lex->create_info.data_file_name=lex->create_info.index_file_name=NullS; sl->having,
lex->create_info.raid_type=lex->create_info.raid_chunks=0; (ORDER*) NULL,
lex->create_info.raid_chunksize=0; sl->options | thd->options,
lex->create_info.if_not_exists=false; result);
lex->create_info.used_fields=0; delete result;
if (res)
if ((create_result=new select_create(tables->db ? tables->db : thd->db, return res;
"ZVEK", &lex->create_info, }
lex->create_list, else
lex->key_list, return -1;
sl->item_list,DUP_IGNORE,true))) }
{
res=mysql_select(thd,tables,sl->item_list,
sl->where,
sl->ftfunc_list,
(ORDER*) NULL,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) some_order,
sl->options | thd->options,
create_result);
if (res)
{
create_result->abort();
delete create_result;
return res;
}
table=create_result->table;
/* List_iterator<Item> it(*(create_result->fields));
Item *item;
while ((item= it++))
fields.push_back(item);*/
if (!(resulting = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
return 1;
resulting->db=tables->db ? tables->db : thd->db;
resulting->real_name=table->real_name;
resulting->name=table->table_name;
resulting->table=table;
}
else
return -1;
}
else // Then we do INSERT from SELECT
{
select_insert *result;
if ((result=new select_insert(table, create_result->fields, DUP_IGNORE, true)))
{
res=mysql_select(thd,tables,sl->item_list,
sl->where,
sl->ftfunc_list,
(ORDER*) some_order,
(ORDER*) sl->group_list.first,
sl->having,
(ORDER*) NULL,
sl->options | thd->options,
result);
delete result;
if (res)
{
delete create_result;
return res;
}
}
else
{
delete create_result;
return -1;
}
}
}
select_result *result; select_result *result;
List<Item> item_list;
List<Item_func_match> ftfunc_list; List<Item_func_match> ftfunc_list;
ftfunc_list.empty(); ftfunc_list.empty();
void(item_list.push_back(new Item_field(NULL,NULL,"*")));
if (lex->exchange) if (lex->exchange)
{ {
if (lex->exchange->dumpfile) if (lex->exchange->dumpfile)
...@@ -129,7 +91,7 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) ...@@ -129,7 +91,7 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
else result=new select_send(); else result=new select_send();
if (result) if (result)
{ {
res=mysql_select(thd,resulting,item_list, res=mysql_select(thd,resulting,list,
NULL, NULL,
ftfunc_list, ftfunc_list,
(ORDER*) NULL, (ORDER*) NULL,
...@@ -144,6 +106,5 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects) ...@@ -144,6 +106,5 @@ int mysql_union(THD *thd,LEX *lex,uint no_of_selects)
} }
else else
res=-1; res=-1;
delete create_result;
return res; return res;
} }
...@@ -15,10 +15,13 @@ ...@@ -15,10 +15,13 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
INCLUDES = -I$(srcdir)/../include -I../include $(openssl_includes) INCLUDES = -I$(srcdir)/../include -I../include $(openssl_includes)
LDADD = libvio.a $(openssl_libs) LDADD = libvio.a $(openssl_libs)
pkglib_LIBRARIES = libvio.a pkglib_LIBRARIES = libvio.a
noinst_PROGRAMS = noinst_PROGRAMS = viotest-ssl
noinst_HEADERS = noinst_HEADERS =
viotest_ssl_SOURCES = viotest-ssl.c
viotest_ssl_LDADD = ../dbug/libdbug.a libvio.a ../mysys/libmysys.a ../strings/libmystrings.a \
libvio.a $(openssl_libs)
libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\ OMIT_DEPENDENCIES = pthread.h stdio.h __stdio.h stdlib.h __stdlib.h math.h\
......
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
*/ */
#include <global.h> #include <global.h>
#ifdef HAVE_OPENSSL
#include <mysql_com.h> #include <mysql_com.h>
#include <errno.h> #include <errno.h>
...@@ -61,9 +64,6 @@ ...@@ -61,9 +64,6 @@
#define HANDLE void * #define HANDLE void *
#endif #endif
#ifdef HAVE_OPENSSL
static void static void
report_errors() report_errors()
{ {
...@@ -105,8 +105,11 @@ int vio_ssl_read(Vio * vio, gptr buf, int size) ...@@ -105,8 +105,11 @@ int vio_ssl_read(Vio * vio, gptr buf, int size)
{ {
int r; int r;
DBUG_ENTER("vio_ssl_read"); DBUG_ENTER("vio_ssl_read");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d, ssl_=%p", vio->sd, buf, size, vio->ssl_));
assert(vio->ssl_!= 0); assert(vio->ssl_!= 0);
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'",SSL_get_cipher_name(vio->ssl_)));
r = SSL_read(vio->ssl_, buf, size); r = SSL_read(vio->ssl_, buf, size);
#ifndef DBUG_OFF #ifndef DBUG_OFF
if ( r< 0) if ( r< 0)
...@@ -123,6 +126,7 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size) ...@@ -123,6 +126,7 @@ int vio_ssl_write(Vio * vio, const gptr buf, int size)
DBUG_ENTER("vio_ssl_write"); DBUG_ENTER("vio_ssl_write");
DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size)); DBUG_PRINT("enter", ("sd=%d, buf=%p, size=%d", vio->sd, buf, size));
assert(vio->ssl_!=0); assert(vio->ssl_!=0);
DBUG_PRINT("info",("SSL_get_cipher_name() = '%s'",SSL_get_cipher_name(vio->ssl_)));
r = SSL_write(vio->ssl_, buf, size); r = SSL_write(vio->ssl_, buf, size);
#ifndef DBUG_OFF #ifndef DBUG_OFF
if (r<0) if (r<0)
...@@ -204,6 +208,7 @@ int vio_ssl_close(Vio * vio) ...@@ -204,6 +208,7 @@ int vio_ssl_close(Vio * vio)
if (r) if (r)
{ {
DBUG_PRINT("error", ("close() failed, error: %d",errno)); DBUG_PRINT("error", ("close() failed, error: %d",errno));
report_errors();
/* FIXME: error handling (not critical for MySQL) */ /* FIXME: error handling (not critical for MySQL) */
} }
vio->type= VIO_CLOSED; vio->type= VIO_CLOSED;
...@@ -289,12 +294,14 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout) ...@@ -289,12 +294,14 @@ my_bool vio_ssl_poll_read(Vio *vio,uint timeout)
/* FIXME: There are some duplicate code in /* FIXME: There are some duplicate code in
* sslaccept()/sslconnect() which maybe can be eliminated * sslaccept()/sslconnect() which maybe can be eliminated
*/ */
Vio *sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd) void sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd)
{ {
X509* client_cert;
char *str;
DBUG_ENTER("sslaccept"); DBUG_ENTER("sslaccept");
DBUG_PRINT("enter", ("sd=%s ptr=%p", sd->desc,ptr)); DBUG_PRINT("enter", ("sd=%s ptr=%p", sd->sd,ptr));
vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE); vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE);
ptr->bio_=0; // ptr->bio_=0;
sd->ssl_=0; sd->ssl_=0;
sd->open_=FALSE; sd->open_=FALSE;
assert(sd != 0); assert(sd != 0);
...@@ -304,9 +311,12 @@ Vio *sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd) ...@@ -304,9 +311,12 @@ Vio *sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd)
{ {
DBUG_PRINT("error", ("SSL_new failure")); DBUG_PRINT("error", ("SSL_new failure"));
report_errors(); report_errors();
DBUG_RETURN(sd); DBUG_VOID_RETURN;
} }
if (!(ptr->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE))) DBUG_PRINT("info", ("ssl_=%p",sd->ssl_));
SSL_set_fd(sd->ssl_,sd->sd);
// SSL_accept(sd->ssl_);
/* if (!(ptr->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE)))
{ {
DBUG_PRINT("error", ("BIO_new_socket failure")); DBUG_PRINT("error", ("BIO_new_socket failure"));
report_errors(); report_errors();
...@@ -314,18 +324,42 @@ Vio *sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd) ...@@ -314,18 +324,42 @@ Vio *sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* sd)
sd->ssl_=0; sd->ssl_=0;
DBUG_RETURN(sd); DBUG_RETURN(sd);
} }
SSL_set_bio(sd->ssl_, ptr->bio_, ptr->bio_); SSL_set_bio(sd->ssl_, ptr->bio_, ptr->bio_);*/
SSL_set_accept_state(sd->ssl_); SSL_set_accept_state(sd->ssl_);
sprintf(ptr->desc_, "VioSSL(%d)", sd->sd); // sprintf(ptr->desc_, "VioSSL(%d)", sd->sd);
/* sd->ssl_cip_ = SSL_get_cipher(sd->ssl_); */ // sd->ssl_cip_ = SSL_get_cipher(sd->ssl_);
sd->open_ = TRUE; sd->open_ = TRUE;
DBUG_RETURN(sd);
client_cert = SSL_get_peer_certificate (sd->ssl_);
if (client_cert != NULL) {
DBUG_PRINT("info",("Client certificate:"));
str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
//CHK_NULL(str);
DBUG_PRINT("info",("\t subject: %s", str));
free (str);
str = X509_NAME_oneline (X509_get_issuer_name (client_cert), 0, 0);
//CHK_NULL(str);
DBUG_PRINT("info",("\t issuer: %s", str));
free (str);
/* We could do all sorts of certificate verification stuff here before
* deallocating the certificate. */
X509_free (client_cert);
} else
DBUG_PRINT("info",("Client does not have certificate."));
DBUG_VOID_RETURN;
} }
Vio *sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd) void sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd)
{ {
char *str;
X509* server_cert;
DBUG_ENTER("sslconnect"); DBUG_ENTER("sslconnect");
DBUG_PRINT("enter", ("sd=%s ptr=%p ctx: %p", sd->desc,ptr,ptr->ssl_context_)); DBUG_PRINT("enter", ("sd=%s ptr=%p ctx: %p", sd->sd,ptr,ptr->ssl_context_));
vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE); vio_reset(sd,VIO_TYPE_SSL,sd->sd,0,FALSE);
sd->bio_=0; sd->bio_=0;
...@@ -339,9 +373,11 @@ Vio *sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd) ...@@ -339,9 +373,11 @@ Vio *sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd)
{ {
DBUG_PRINT("error", ("SSL_new failure")); DBUG_PRINT("error", ("SSL_new failure"));
report_errors(); report_errors();
DBUG_RETURN(sd); DBUG_VOID_RETURN;
} }
if (!(sd->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE))) DBUG_PRINT("info", ("ssl_=%p",sd->ssl_));
printf("ssl_=%p\n",sd->ssl_);
/* if (!(sd->bio_ = BIO_new_socket(sd->sd, BIO_NOCLOSE)))
{ {
DBUG_PRINT("error", ("BIO_new_socket failure")); DBUG_PRINT("error", ("BIO_new_socket failure"));
report_errors(); report_errors();
...@@ -349,12 +385,32 @@ Vio *sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd) ...@@ -349,12 +385,32 @@ Vio *sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* sd)
sd->ssl_=0; sd->ssl_=0;
DBUG_RETURN(sd); DBUG_RETURN(sd);
} }
SSL_set_bio(sd->ssl_, sd->bio_, sd->bio_); SSL_set_bio(sd->ssl_, sd->bio_, sd->bio_);*/
SSL_set_fd (sd->ssl_, sd->sd);
SSL_set_connect_state(sd->ssl_); SSL_set_connect_state(sd->ssl_);
/* sprintf(ptr->desc_, "VioSSL(%d)", sd->sd);
sd->ssl_cip_ = SSL_get_cipher(sd->ssl_);*/ server_cert = SSL_get_peer_certificate (sd->ssl_);
if (server_cert != NULL) {
DBUG_PRINT("info",("Server certificate:"));
str = X509_NAME_oneline (X509_get_subject_name (server_cert), 0, 0);
DBUG_PRINT("info",("\t subject: %s", str));
free (str);
str = X509_NAME_oneline (X509_get_issuer_name (server_cert), 0, 0);
DBUG_PRINT("info",("\t issuer: %s\n", str));
free (str);
/* We could do all sorts of certificate verification stuff here before
* deallocating the certificate. */
X509_free(server_cert);
} else
DBUG_PRINT("info",("Server does not have certificate."));
// sd->ssl_cip_ = SSL_get_cipher(sd->ssl_);
sd->open_ = TRUE; sd->open_ = TRUE;
DBUG_RETURN(sd); DBUG_VOID_RETURN;
} }
......
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
#include <global.h> #include <global.h>
#ifdef HAVE_OPENSSL
#include <my_sys.h> #include <my_sys.h>
#include <mysql_com.h> #include <mysql_com.h>
#include <violite.h> #include <violite.h>
#ifdef HAVE_OPENSSL
static bool ssl_algorithms_added = FALSE; static bool ssl_algorithms_added = FALSE;
static bool ssl_error_strings_loaded= FALSE; static bool ssl_error_strings_loaded= FALSE;
...@@ -142,9 +160,9 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, ...@@ -142,9 +160,9 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
if (!ssl_algorithms_added) if (!ssl_algorithms_added)
{ {
DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()")); DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
ssl_algorithms_added = TRUE; ssl_algorithms_added = TRUE;
SSLeay_add_ssl_algorithms(); OpenSSL_add_all_algorithms();
} }
if (!ssl_error_strings_loaded) if (!ssl_error_strings_loaded)
{ {
...@@ -152,7 +170,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, ...@@ -152,7 +170,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
ssl_error_strings_loaded = TRUE; ssl_error_strings_loaded = TRUE;
SSL_load_error_strings(); SSL_load_error_strings();
} }
ptr->ssl_method_ = SSLv3_client_method(); ptr->ssl_method_ = SSLv23_client_method();
ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_); ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_);
DBUG_PRINT("info", ("ssl_context_: %p",ptr->ssl_context_)); DBUG_PRINT("info", ("ssl_context_: %p",ptr->ssl_context_));
if (ptr->ssl_context_ == 0) if (ptr->ssl_context_ == 0)
...@@ -186,6 +204,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file, ...@@ -186,6 +204,7 @@ struct st_VioSSLConnectorFd* new_VioSSLConnectorFd(const char* key_file,
DBUG_RETURN(ptr); DBUG_RETURN(ptr);
ctor_failure: ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_PRINT("exit", ("there was an error"));
my_free((gptr)ptr,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -216,9 +235,10 @@ new_VioSSLAcceptorFd(const char* key_file, ...@@ -216,9 +235,10 @@ new_VioSSLAcceptorFd(const char* key_file,
if (!ssl_algorithms_added) if (!ssl_algorithms_added)
{ {
DBUG_PRINT("info", ("todo: SSLeay_add_ssl_algorithms()")); DBUG_PRINT("info", ("todo: OpenSSL_add_all_algorithms()"));
ssl_algorithms_added = TRUE; ssl_algorithms_added = TRUE;
SSLeay_add_ssl_algorithms(); OpenSSL_add_all_algorithms();
} }
if (!ssl_error_strings_loaded) if (!ssl_error_strings_loaded)
{ {
...@@ -226,7 +246,7 @@ new_VioSSLAcceptorFd(const char* key_file, ...@@ -226,7 +246,7 @@ new_VioSSLAcceptorFd(const char* key_file,
ssl_error_strings_loaded = TRUE; ssl_error_strings_loaded = TRUE;
SSL_load_error_strings(); SSL_load_error_strings();
} }
ptr->ssl_method_ = SSLv3_server_method(); ptr->ssl_method_ = SSLv23_server_method();
ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_); ptr->ssl_context_ = SSL_CTX_new(ptr->ssl_method_);
if (ptr->ssl_context_==0) if (ptr->ssl_context_==0)
{ {
...@@ -267,6 +287,7 @@ new_VioSSLAcceptorFd(const char* key_file, ...@@ -267,6 +287,7 @@ new_VioSSLAcceptorFd(const char* key_file,
DBUG_RETURN(ptr); DBUG_RETURN(ptr);
ctor_failure: ctor_failure:
DBUG_PRINT("exit", ("there was an error")); DBUG_PRINT("exit", ("there was an error"));
my_free((gptr)ptr,MYF(0));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
#include "all.h" #include <global.h>
#ifdef HAVE_OPENSSL
#include <my_sys.h>
#include <m_string.h>
#include <m_ctype.h>
#include "mysql.h"
#include "errmsg.h"
#include <my_dir.h>
#ifndef __GNU_LIBRARY__
#define __GNU_LIBRARY__ // Skip warnings in getopt.h
#endif
#include <getopt.h>
//#include "my_readline.h"
#include <signal.h>
#include <violite.h>
#include <sys/types.h> const char *VER="0.1";
#include <sys/socket.h>
#include <stdio.h>
#include <unistd.h>
#ifndef DBUG_OFF
const char *default_dbug_option="d:t:O,/tmp/viotest-ssl.trace";
#endif
void void
fatal_error( const char* r) fatal_error( const char* r)
{ {
...@@ -16,8 +31,8 @@ fatal_error( const char* r) ...@@ -16,8 +31,8 @@ fatal_error( const char* r)
void void
print_usage() print_usage()
{ {
printf("viossltest: testing SSL virtual IO. Usage:\n"); printf("viossl-test: testing SSL virtual IO. Usage:\n");
printf("viossltest server-key server-cert client-key client-cert [CAfile] [CApath]\n"); printf("viossl-test server-key server-cert client-key client-cert [CAfile] [CApath]\n");
} }
int int
...@@ -30,7 +45,17 @@ main( int argc, ...@@ -30,7 +45,17 @@ main( int argc,
char* client_cert = 0; char* client_cert = 0;
char* ca_file = 0; char* ca_file = 0;
char* ca_path = 0; char* ca_path = 0;
int sv[2]; int child_pid,sv[2];
struct st_VioSSLAcceptorFd* ssl_acceptor=0;
struct st_VioSSLConnectorFd* ssl_connector=0;
Vio* client_vio=0;
Vio* server_vio=0;
MY_INIT(argv[0]);
// DBUG_ENTER("main");
DBUG_PROCESS(argv[0]);
DBUG_PUSH(default_dbug_option);
if (argc<5) if (argc<5)
{ {
...@@ -38,9 +63,6 @@ main( int argc, ...@@ -38,9 +63,6 @@ main( int argc,
return 1; return 1;
} }
if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
fatal_error("socketpair");
server_key = argv[1]; server_key = argv[1];
server_cert = argv[2]; server_cert = argv[2];
client_key = argv[3]; client_key = argv[3];
...@@ -56,49 +78,63 @@ main( int argc, ...@@ -56,49 +78,63 @@ main( int argc,
if (ca_path!=0) if (ca_path!=0)
printf("CApath : %s\n", ca_path); printf("CApath : %s\n", ca_path);
VIO_NS::VioSSLAcceptorFd* ssl_acceptor = new VIO_NS::VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
VIO_NS::VioSSLConnectorFd* ssl_connector = new VIO_NS::VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
printf("Socketpair: %d , %d\n", sv[0], sv[1]); if (socketpair(PF_UNIX, SOCK_STREAM, IPPROTO_IP, sv)==-1)
fatal_error("socketpair");
ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path);
ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path);
VIO_NS::VioSSL* client_vio = ssl_connector->connect(sv[0]); client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
VIO_NS::VioSSL* server_vio = ssl_acceptor->accept(sv[1]); client_vio->sd = sv[0];
sslconnect(ssl_connector,client_vio);
server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0));
server_vio->sd = sv[1];
sslaccept(ssl_acceptor,server_vio);
printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);
int child_pid = fork(); child_pid = fork();
if (child_pid==-1) { if (child_pid==-1) {
delete ssl_acceptor; my_free((gptr)ssl_acceptor,MYF(0));
delete ssl_connector; my_free((gptr)ssl_connector,MYF(0));
fatal_error("fork"); fatal_error("fork");
} }
if (child_pid==0) { if (child_pid==0) {
//child, therefore, client //child, therefore, client
char xbuf[100]; char xbuf[100];
int r = client_vio->read(xbuf, sizeof(xbuf)); int r = vio_ssl_read(client_vio,xbuf, sizeof(xbuf));
if (r<=0) { if (r<=0) {
delete ssl_acceptor; my_free((gptr)ssl_acceptor,MYF(0));
delete ssl_connector; my_free((gptr)ssl_connector,MYF(0));
fatal_error("client:SSL_read"); fatal_error("client:SSL_read");
} }
printf("*** client cipher %s\n",client_vio->cipher_description()); // printf("*** client cipher %s\n",client_vio->cipher_description());
xbuf[r] = 0; xbuf[r] = 0;
printf("client:got %s\n", xbuf); printf("client:got %s\n", xbuf);
delete client_vio; my_free((gptr)client_vio,MYF(0));
delete ssl_acceptor; my_free((gptr)ssl_acceptor,MYF(0));
delete ssl_connector; my_free((gptr)ssl_connector,MYF(0));
sleep(1); sleep(1);
} else { } else {
const char* s = "Huhuhuh"; const char* s = "Huhuhuh";
int r = server_vio->write((void *)s, strlen(s)); int r = vio_ssl_write(server_vio,(gptr)s, strlen(s));
if (r<=0) { if (r<=0) {
delete ssl_acceptor; my_free((gptr)ssl_acceptor,MYF(0));
delete ssl_connector; my_free((gptr)ssl_connector,MYF(0));
fatal_error("server:SSL_write"); fatal_error("server:SSL_write");
} }
printf("*** server cipher %s\n",server_vio->cipher_description()); // printf("*** server cipher %s\n",server_vio->cipher_description());
delete server_vio; my_free((gptr)server_vio,MYF(0));
delete ssl_acceptor; my_free((gptr)ssl_acceptor,MYF(0));
delete ssl_connector; my_free((gptr)ssl_connector,MYF(0));
sleep(1); sleep(1);
} }
return 0;
}
#else /* HAVE_OPENSSL */
int main() {
return 0;
} }
#endif /* HAVE_OPENSSL */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment