Annotation of doc/build/loncapasqldatabase.html, revision 1.9

1.1       harris41    1: <HTML>
                      2: <HEAD>
                      3: <TITLE>LON-CAPA SQL Database Documentation</TITLE>
                      4: </HEAD>
                      5: <BODY>
                      6: <H1>LON-CAPA SQL Database Documentation</H1>
                      7: <P>
                      8: Scott Harrison
                      9: </P>
                     10: <P>
1.9     ! harris41   11: Last updated: 02/14/2001
1.1       harris41   12: </P>
1.2       harris41   13: <P>
1.1       harris41   14: This file describes issues associated with LON-CAPA
                     15: and a SQL database.
                     16: </P>
1.5       harris41   17: <H2>Latest HOWTO</H2>
1.2       harris41   18: <P>
1.4       harris41   19: <UL>
1.9     ! harris41   20: <LI>Important notes
1.4       harris41   21: <LI>Current status of documentation</LI>
                     22: <LI>Current status of implementation</LI>
                     23: <LI>Purpose within LON-CAPA</LI>
1.8       harris41   24: <LI>Dependencies</LI>
1.4       harris41   25: <LI>Installation</LI>
                     26: <LI>Installation from source</LI>
                     27: <LI>Configuration (automated)</LI>
                     28: <LI>Manual configuration</LI>
                     29: <LI>Testing</LI>
                     30: <LI>Example sections of code relevant to LON-CAPA</LI>
                     31: </UL>
                     32: </P>
1.9     ! harris41   33: <H2>Important notes</H2>
        !            34: <P>
        !            35: It might be worthwhile to look at /usr/local/mysql/manual.html.
        !            36: It is quite in depth.
        !            37: </P>
1.5       harris41   38: <H2>Current status of documentation</H2>
1.4       harris41   39: <P>
1.2       harris41   40: I am going to begin documentation by inserting what notes
                     41: I have into this file.  I will be subsequently rearranging
1.4       harris41   42: them and editing them based on the tests that I conduct.
1.2       harris41   43: I am trying to make sure that documentation, installation,
                     44: and run-time issues are all consistent and correct.  The
                     45: current status of everything is that it works and has
                     46: been minimally tested, but things need to be cleaned up
                     47: and checked again!
                     48: </P>
1.5       harris41   49: <H2>Current status of implementation</H2>
1.4       harris41   50: <P>
1.6       harris41   51: Need to
                     52: <UL>
                     53: <LI>Installation: Fix binary file listings for user permissions and ownership.
                     54: <LI>Installation: Make sure sql server starts, and if database does not
                     55: exist, then create. (/etc/rc.d).
                     56: <LI>Processes: Make sure loncron initiates lonsql on library machines.
                     57: <LI>Read in metadata from right place periodically.
                     58: <LI>Implement tested perl module handler.
                     59: </UL>
                     60: <P>
1.4       harris41   61: Right now, a lot of "feasibility" work has been done.
                     62: Recipes for manual installation and configuration have
                     63: been gathered.  Network connectivity of lond->lonsql->lond->lonc
                     64: type tests have been performed.  A binary installation
1.7       harris41   65: has been compiled in an RPM (LON-CAPA-mysql, with perl components
                     66: a part of LON-CAPA-systemperl).
1.4       harris41   67: The most lacking test in terms of feasibility has
                     68: been looking at benchmarks to analyze the load at which
                     69: the SQL database can efficiently allow many users to
                     70: make simultaneous requests of the metadata database.
                     71: </P>
                     72: <P>
                     73: Documentation has been pieced together over time.  But,
                     74: as mentioned in the previous section, it needs an
                     75: overhaul.
                     76: </P>
                     77: <P>
                     78: The binary installation has some quirks associated with it.
                     79: Some of the user permissions are wrong, although this is
                     80: benign.  Also, other options of binary installation (such
                     81: as using binary RPMs put together by others) were dismissed
                     82: given the difficulty of getting differing combinations of
                     83: these external RPMs to work together.
                     84: </P>
                     85: <P>
                     86: Most configuration questions have been initially worked out
                     87: to the point of getting this SQL software component working,
                     88: however there may be more optimal approaches than currently
                     89: exist.
                     90: </P>
1.5       harris41   91: <H2>Purpose within LON-CAPA</H2>
1.4       harris41   92: <P>
                     93: LON-CAPA is meant to distribute A LOT of educational content
                     94: to A LOT of people.  It is ineffective to directly rely on contents
                     95: within the ext2 filesystem to be speedily scanned for 
                     96: on-the-fly searches of content descriptions.  (Simply put,
                     97: it takes a cumbersome amount of time to open, read, analyze, and
                     98: close thousands of files.)
                     99: </P>
                    100: <P>
                    101: The solution is to hash-index various data fields that are
                    102: descriptive of the educational resources on a LON-CAPA server
                    103: machine.  Descriptive data fields are referred to as
                    104: "metadata".  The question then arises as to how this metadata
                    105: is handled in terms of the rest of the LON-CAPA network
                    106: without burdening client and daemon processes.  I now
                    107: answer this question in the format of Problem and Solution
                    108: below.
                    109: </P>
                    110: <P>
                    111: <PRE>
                    112: PROBLEM SITUATION:
                    113: 
                    114:   If Server A wants data from Server B, Server A uses a lonc process to
                    115:   send a database command to a Server B lond process.
                    116:     lonc= loncapa client process    A-lonc= a lonc process on Server A
                    117:     lond= loncapa daemon process
                    118: 
                    119:                  database command
                    120:     A-lonc  --------TCP/IP----------------> B-lond
                    121: 
                    122:   The problem emerges that A-lonc and B-lond are kept waiting for the
                    123:   MySQL server to "do its stuff", or in other words, perform the conceivably
                    124:   sophisticated, data-intensive, time-sucking database transaction.  By tying
                    125:   up a lonc and lond process, this significantly cripples the capabilities
                    126:   of LON-CAPA servers. 
                    127: 
                    128:   While commercial databases have a variety of features that ATTEMPT to
                    129:   deal with this, freeware databases are still experimenting and exploring
                    130:   with different schemes with varying degrees of performance stability.
                    131: 
                    132: THE SOLUTION:
                    133: 
                    134:   A separate daemon process was created that B-lond works with to
                    135:   handle database requests.  This daemon process is called "lonsql".
                    136: 
                    137:   So,
                    138:                 database command
                    139:   A-lonc  ---------TCP/IP-----------------> B-lond =====> B-lonsql
                    140:          <---------------------------------/                |
                    141:            "ok, I'll get back to you..."                    |
                    142:                                                             |
                    143:                                                             /
                    144:   A-lond  <-------------------------------  B-lonc   <======
                    145:            "Guess what? I have the result!"
                    146: 
                    147:   Of course, depending on success or failure, the messages may vary,
                    148:   but the principle remains the same where a separate pool of children
                    149:   processes (lonsql's) handle the MySQL database manipulations.
                    150: </PRE>
                    151: </P>
1.8       harris41  152: <H2>Dependencies</H2>
                    153: <P>
                    154: I believe (but am not 100% confident) that the following
                    155: RPMs are necessary (in addition to the current ones
                    156: in rpm_list.txt) to run MySQL.  Basically I discovered these
                    157: dependencies while trying to do external RPM based installs.
                    158: I assume, and sometimes found, that these dependencies apply
                    159: to tarball-based distributions too.  (So to play it on the
                    160: safe side, I am going to include these RPMs as part of the
                    161: core, minimal RPM set.)
                    162: <UL>
                    163: <LI>egcs-1.1.2-30</LI>
                    164: <LI>cpp-1.1.2-30</LI>
                    165: <LI>glibc-devel-2.1.3-15</LI>
                    166: <LI>zlib-devel-1.1.3-6</LI>
                    167: </UL>
                    168: </P>
1.5       harris41  169: <H2>Installation</H2>
1.4       harris41  170: <P>
                    171: Installation of the LON-CAPA SQL database normally occurs
                    172: by default when using the LON-CAPA installation CD
                    173: (see http://install.lon-capa.org).  It is installed
                    174: as the LON-CAPA-mysql RPM.  This RPM encodes for the MySQL
1.7       harris41  175: engine.  Related perl interfaces (Perl::DBI, Perl::Msql-Mysql)
                    176: are encoded in the LON-CAPA-systemperl RPM.
1.4       harris41  177: </P>
                    178: <P>
                    179: The three components of a MySQL installation for the
                    180: LON-CAPA system are further described immediately below.
                    181: <TABLE BORDER="0">
                    182: <TR><TD COLSPAN="2"><STRONG>Perl::DBI module</STRONG>-
                    183: the API "front-end"...</TD></TR>
                    184: <TR><TD WIDTH="10%"></TD><TD>database interface module for organizing generic
                    185: database commands which are independent of specific
                    186: database implementation (such as MySQL, mSQL, Postgres, etc).
                    187: </TD></TR>
                    188: <TR><TD COLSPAN="2"><STRONG>Perl::MySQL module</STRONG>-
                    189: the API "mid-section"...</TD></TR>
                    190: <TR><TD WIDTH="10%"></TD><TD>the module to directly interface with the actual
                    191: MySQL database engine</TD></TR>
                    192: <TR><TD COLSPAN="2"><STRONG>MySQL database engine</STRONG>-
                    193: the "back-end"...</TD></TR>
                    194: <TR><TD WIDTH="10%"></TD><TD>the binary installation (compiled either
                    195: from source or pre-compiled file listings) which provides the
                    196: actual MySQL functionality on the system</TD></TR>
                    197: </TABLE>
                    198: </P>
1.5       harris41  199: <H2>Installation from source</H2>
1.4       harris41  200: <P>
1.8       harris41  201: Note: the mysql site recommends that Linux users install by
                    202: using the MySQL RPMs (MySQL-client, MySQL, MySQL-shared, etc).
                    203: While these RPMs work, I was unsuccessful at integrating
                    204: this RPM-installed database with perl modules from www.cpan.org.
                    205: Hence, I <STRONG>strongly</STRONG> recommend that, when installing
                    206: from "source", MySQL and the perl components be in fact installed
                    207: from their tarballs (.tar.gz, .tgz).  (Perl components, when installed
                    208: from RPMs, also wound up in incorrect locations on the disk.)
                    209: Do not coordinate a source install with externally made RPMs!
                    210: It is, of course, okay to use LON-CAPA RPMs such as LON-CAPA-systemperl
                    211: and LON-CAPA-mysql since we, in fact, made these RPMs correctly :).
                    212: <UL>
                    213: <LI>http://www.cpan.org/authors/id/JWIED/Msql-Mysql-modules-1.2215.tar.gz
                    214: <BR>This tarball Released 20th August 2000
                    215: <LI>http://www.mysql.com/Downloads/MySQL-3.23/mysql-3.23.33-pc-linux-gnu-i686.tar.gz
                    216: <BR>This tarball Last changed 2000-11-11
                    217: <BR>This is actually a binary tarball (as opposed to source code
                    218: that is subsequently compiled).
1.9     ! harris41  219: <LI>http://www.cpan.org/authors/id/TIMB/DBI-1.14.tar.gz
        !           220: <BR>This tarball Released 14th June 2000
1.8       harris41  221: </UL>
1.9     ! harris41  222: </P>
        !           223: <P>So, here is exactly how I installed MySQL-3.23. (Note that all files
        !           224: wind up in /usr/local/mysql-3.23.33-pc-linux-gnu-i686 except for
        !           225: a link from /usr/local/mysql to /usr/local/mysql-3.23.33-pc-linux-gnu-i686
        !           226: and some files involved in system process handling (/etc/rc.d/*/*mysql).
        !           227: </P>
        !           228: <P>This is how I installed the Msql-Mysql-modules perl modules.
        !           229: <PRE>
        !           230: [root@fenchurch Msql-Mysql-modules-1.2215]# perl Makefile.PL 
        !           231: Which drivers do you want to install?
        !           232: 
        !           233:     1)	MySQL only
        !           234:     2)	mSQL only (either of mSQL 1 or mSQL 2)
        !           235:     3)  MySQL and mSQL (either of mSQL 1 or mSQL 2)
        !           236: 
        !           237:     4)  mSQL 1 and mSQL 2
        !           238:     5)  MySQL, mSQL 1 and mSQL 2
        !           239: 
        !           240: Enter the appropriate number:  [3] 1
        !           241: 
        !           242: 
        !           243: Do you want to install the MysqlPerl emulation? You might keep your old
        !           244: Mysql module (to be distinguished from DBD::mysql!) if you are concerned
        !           245: about compatibility to existing applications! [y] n
        !           246: [root@fenchurch Msql-Mysql-modules-1.2215]# make
        !           247: [root@fenchurch Msql-Mysql-modules-1.2215]# make test
        !           248: make[1]: Entering directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
        !           249: make[1]: Leaving directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
        !           250: make[1]: Entering directory `/home/user/Msql-Mysql-modules-1.2215/mysql'
        !           251: PERL_DL_NONLAZY=1 /usr/bin/perl -I../blib/arch -I../blib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t
        !           252: t/00base............ok
        !           253: t/10dsnlist.........ok
        !           254: t/20createdrop......ok
        !           255: t/30insertfetch.....ok
        !           256: t/40bindparam.......ok
        !           257: t/40blobs...........ok
        !           258: t/40listfields......ok
        !           259: t/40nulls...........ok
        !           260: t/40numrows.........ok
        !           261: t/50chopblanks......ok
        !           262: t/50commit..........ok
        !           263: t/60leaks...........skipping test on this platform
        !           264: t/ak-dbd............ok
        !           265: t/akmisc............ok
        !           266: t/dbdadmin..........ok
        !           267: t/mysql.............ok
        !           268: t/mysql2............ok
        !           269: All tests successful, 1 test skipped.
        !           270: Files=17,  Tests=732, 40 wallclock secs (15.38 cusr +  1.30 csys = 16.68 CPU)
        !           271: [root@fenchurch Msql-Mysql-modules-1.2215]# make install
        !           272: 
        !           273: These files are installed.
        !           274: /usr/bin/dbimon
        !           275: /usr/lib/perl5/man/man3/Bundle::DBD::mysql.3
        !           276: /usr/lib/perl5/man/man3/DBD::mysql.3
        !           277: /usr/lib/perl5/man/man3/Mysql.3
        !           278: /usr/lib/perl5/site_perl/5.005/i386-linux/Bundle/DBD/mysql.pm
        !           279: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/mysql.pm
        !           280: /usr/lib/perl5/site_perl/5.005/i386-linux/Mysql.pm
        !           281: /usr/lib/perl5/site_perl/5.005/i386-linux/Mysql/Statement.pm
        !           282: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/mysql/mysql.bs
        !           283: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBD/mysql/mysql.so
        !           284: /usr/man/man1/dbimon.1
        !           285: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/Msql-Mysql-modules/.packlist
        !           286: </PRE>
        !           287: </P>
        !           288: <P>
        !           289: This is how I installed the DBI perl modules.
        !           290: <PRE>
        !           291: [root@fenchurch DBI-1.14]# perl Makefile.PL
        !           292: *** Note:
        !           293:     The optional PlRPC-modules (RPC::PlServer etc) are not installed.
        !           294:     If you want to use the DBD::Proxy driver and DBI::ProxyServer
        !           295:     modules, then you'll need to install the RPC::PlServer, RPC::PlClient,
        !           296:     Storable and Net::Daemon modules. The CPAN Bundle::DBI may help you.
        !           297:     You can install them any time after installing the DBI.
        !           298:     You do *not* need these modules for typical DBI usage.
        !           299: 
        !           300: Optional modules are available from any CPAN mirror, in particular
        !           301:     http://www.perl.com/CPAN/modules/by-module
        !           302:     http://www.perl.org/CPAN/modules/by-module
        !           303:     ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module
        !           304: 
        !           305: Checking if your kit is complete...
        !           306: Looks good
        !           307: Writing Makefile for DBI
        !           308: 
        !           309:     Remember to actually *read* the README file!
        !           310:     Use  'make' to build the software (dmake or nmake on Windows).
        !           311:     Then 'make test' to execute self tests.
        !           312:     Then 'make install' to install the DBI and then delete this working
        !           313:     directory before unpacking and building any DBD::* drivers.
        !           314: 
        !           315: [root@fenchurch DBI-1.14]# make
        !           316: [root@fenchurch DBI-1.14]# make test
        !           317: PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 -e 'use Test::Harness qw(&runtests $verbose); $verbose=0; runtests @ARGV;' t/*.t
        !           318: t/basics............ok
        !           319: t/dbidrv............ok
        !           320: t/examp.............ok
        !           321: t/meta..............ok
        !           322: t/proxy.............skipping test on this platform
        !           323: t/shell.............ok
        !           324: t/subclass..........ok
        !           325: All tests successful, 1 test skipped.
        !           326: Files=7,  Tests=179,  7 wallclock secs ( 6.46 cusr +  0.49 csys =  6.95 CPU)
        !           327: PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 test.pl
        !           328: test.pl 
        !           329: DBI test application $Revision: 10.4 $
        !           330: Using /home/user/DBI-1.14/blib
        !           331: Switch: DBI 1.14 by Tim Bunce, 1.14
        !           332: Available Drivers: ADO, ExampleP, Multiplex, Proxy, mysql
        !           333: dbi:ExampleP:: testing 5 sets of 20 connections:
        !           334: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
        !           335: Disconnecting...
        !           336: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
        !           337: Disconnecting...
        !           338: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
        !           339: Disconnecting...
        !           340: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
        !           341: Disconnecting...
        !           342: Connecting... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 
        !           343: Disconnecting...
        !           344: Made 100 connections in  0 wallclock secs ( 0.22 usr +  0.03 sys =  0.25 CPU)
        !           345: 
        !           346: Testing handle creation speed...
        !           347: 5000 NullP statement handles cycled in 6.6 cpu+sys seconds (762 per sec)
        !           348: 
        !           349: test.pl done
        !           350: 
        !           351: [root@fenchurch DBI-1.14]# make install
        !           352: These files are installed.
        !           353: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/.packlist
        !           354: /usr/bin/dbiproxy
        !           355: /usr/bin/dbish
        !           356: /usr/lib/perl5/man/man3/Bundle::DBI.3
        !           357: /usr/lib/perl5/man/man3/DBD::ADO.3
        !           358: /usr/lib/perl5/man/man3/DBD::Multiplex.3
        !           359: /usr/lib/perl5/man/man3/DBD::Proxy.3
        !           360: /usr/lib/perl5/man/man3/DBI.3
        !           361: /usr/lib/perl5/man/man3/DBI::DBD.3
        !           362: /usr/lib/perl5/man/man3/DBI::FAQ.3
        !           363: /usr/lib/perl5/man/man3/DBI::Format.3
        !           364: /usr/lib/perl5/man/man3/DBI::ProxyServer.3
        !           365: /usr/lib/perl5/man/man3/DBI::Shell.3
        !           366: /usr/lib/perl5/man/man3/DBI::W32ODBC.3
        !           367: /usr/lib/perl5/man/man3/Win32::DBIODBC.3
        !           368: /usr/lib/perl5/site_perl/5.005/i386-linux/Bundle/DBI.pm
        !           369: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/ADO.pm
        !           370: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/ExampleP.pm
        !           371: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Multiplex.pm
        !           372: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/NullP.pm
        !           373: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Proxy.pm
        !           374: /usr/lib/perl5/site_perl/5.005/i386-linux/DBD/Sponge.pm
        !           375: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI.pm
        !           376: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/DBD.pm
        !           377: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/FAQ.pm
        !           378: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/Format.pm
        !           379: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/ProxyServer.pm
        !           380: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/Shell.pm
        !           381: /usr/lib/perl5/site_perl/5.005/i386-linux/DBI/W32ODBC.pm
        !           382: /usr/lib/perl5/site_perl/5.005/i386-linux/Win32/DBIODBC.pm
        !           383: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBI.bs
        !           384: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBI.so
        !           385: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/DBIXS.h
        !           386: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/Driver.xst
        !           387: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbd_xsh.h
        !           388: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbi_sql.h
        !           389: /usr/lib/perl5/site_perl/5.005/i386-linux/auto/DBI/dbipport.h
        !           390: /usr/man/man1/dbiproxy.1
        !           391: /usr/man/man1/dbish.1
        !           392: </PRE>
1.8       harris41  393: </P>
                    394: <FONT COLOR="green"> old notes in green
                    395: <P>
1.4       harris41  396: The following set of tarballs was found to work together
                    397: properly on a LON-CAPA RedHat 6.2 system:
                    398: <UL>
                    399: <LI>DBI-1.13.tar.gz
                    400: <LI>Msql-Mysql-modules-1.2209.tar.gz
                    401: <LI>mysql-3.22.32.tar.gz
                    402: </UL>
                    403: </P>
                    404: <P>
                    405: Installation was simply a matter of following the instructions
                    406: and typing the several "make" commands for each 
                    407: </P>
1.8       harris41  408: </FONT>
1.5       harris41  409: <H2>Configuration (automated)</H2>
1.4       harris41  410: <P>
                    411: Not yet developed.  This will be part of an interface
                    412: present on LON-CAPA systems that can be launched by
                    413: entering the command <TT>/usr/sbin/loncapaconfig</TT>.
                    414: </P>
1.5       harris41  415: <H2>Manual configuration</H2>
1.4       harris41  416: <P>
                    417: This is not complete.
                    418: </P>
                    419: <P>
                    420: <STRONG>Starting the mysql daemon</STRONG>: Login on the Linux
                    421: system as user 'www'.  Enter the command
                    422: <TT>/usr/local/bin/safe_mysqld &</TT>
                    423: </P>
                    424: <P>
                    425: <STRONG>Set a password for 'root'</STRONG>:
                    426: <TT>/usr/local/bin/mysqladmin -u root password 'new-password'</TT>
                    427: </P>
                    428: <P>
                    429: <STRONG>Adding a user</STRONG>:  Start the mysql daemon.  Login to the
                    430: mysql system as root (<TT>mysql -u root -p mysql</TT>)
                    431: and enter the right password (for instance 'newmysql').  Add the user
                    432: www
                    433: <PRE>
                    434: INSERT INTO user (Host, User, Password)
                    435: VALUES ('localhost','www',password('newmysql'));
                    436: </PRE>
                    437: </P>
                    438: <P>
                    439: <STRONG>Granting privileges to user 'www'</STRONG>:
                    440: <PRE>
                    441: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
                    442: FLUSH PRIVILEGES;
                    443: </PRE>
                    444: </P>
                    445: <P>
                    446: <STRONG>Set the SQL server to start upon system startup</STRONG>:
                    447: Copy support-files/mysql.server to the right place on the system
                    448: (/etc/rc.d/...).
                    449: </P>
1.1       harris41  450: <P>
1.5       harris41  451: <STRONG>The Perl API</STRONG>
1.2       harris41  452: <PRE>
                    453:    $dbh = DBI->connect(	"DBI:mysql:loncapa",
                    454: 			"www",
                    455: 			"SOMEPASSWORD",
                    456: 			{ RaiseError =>0,PrintError=>0});
                    457: 
                    458: There is an obvious need to CONNECT to the database, and in order to do
                    459: this, there must be:
                    460:   a RUNNING mysql daemon;
                    461:   a DATABASE named "loncapa";
                    462:   a USER named "www";
                    463:   and an ABILITY for LON-CAPA on one machine to access
                    464:        SQL database on another machine;
                    465:   
                    466: So, here are some notes on implementing these configurations.
                    467: 
                    468: ** RUNNING mysql daemon (safe_mysqld method)
                    469: 
                    470: The recommended way to run the MySQL daemon is as a non-root user
                    471: (probably www)...
                    472: 
                    473: so, 1) login as user www on the linux machine
                    474:     2) start the mysql daemon as /usr/local/bin/safe_mysqld &
                    475: 
                    476: safe_mysqld only works if the local installation of MySQL is set to the
                    477: right directory permissions which I found to be:
                    478: chown www:users /usr/local/var/mysql
                    479: chown www:users /usr/local/lib/mysql
                    480: chown -R www:users /usr/local/mysql
                    481: chown www:users /usr/local/include/mysql
                    482: chown www:users /usr/local/var
                    483: 
                    484: ** DATABASE named "loncapa"
                    485: 
                    486: As user www, run this command
                    487:     mysql -u root -p mysql
                    488: enter the password as SOMEPASSWORD
                    489: 
                    490: This allows you to manually enter MySQL commands.
                    491: The MySQL command to generate the loncapa DATABASE is:
                    492: 
                    493: CREATE DATABASE 'loncapa';
                    494: 
                    495: ** USER named "www"
                    496: 
                    497: As user www, run this command
                    498:     mysql -u root -p mysql
                    499: enter the password as SOMEPASSWORD
                    500: 
                    501: To add the user www to the MySQL server, and grant all
                    502: privileges on *.* to www@localhost identified by 'SOMEPASSWORD'
                    503: with grant option;
                    504: 
                    505: INSERT INTO user (Host, User, Password)
                    506: VALUES ('localhost','www',password('SOMEPASSWORD'));
                    507: 
                    508: GRANT ALL PRIVILEGES ON *.* TO www@localhost;
                    509: 
                    510: FLUSH PRIVILEGES;
                    511: 
                    512: ** ABILITY for LON-CAPA machines to communicate with SQL databases on
                    513:    other LON-CAPA machines
                    514: 
1.5       harris41  515: An up-to-date lond and lonsql.
                    516: </PRE>
                    517: </P>
                    518: <H2>Testing</H2>
                    519: <P>
                    520: <PRE>
                    521: <STRONG>** TEST the database connection with my current tester.pl code
                    522: which mimics what command will eventually be sent through lonc.</STRONG>
1.2       harris41  523: 
1.5       harris41  524: $reply=reply(
                    525:     "querysend:SELECT * FROM general_information WHERE Id='AAAAA'",$lonID);
                    526: </PRE>
                    527: </P>
                    528: <H2>Example sections of code relevant to LON-CAPA</H2>
                    529: <P>
1.2       harris41  530: Here are excerpts of code which implement the above handling:
1.5       harris41  531: </P>
                    532: <P>
                    533: <PRE>
                    534: <STRONG>**LONSQL
1.2       harris41  535: A subroutine from "lonsql" which establishes a child process for handling
1.5       harris41  536: database interactions.</STRONG>
1.2       harris41  537: 
                    538: sub make_new_child {
                    539:     my $pid;
                    540:     my $sigset;
                    541:     
                    542:     # block signal for fork
                    543:     $sigset = POSIX::SigSet->new(SIGINT);
                    544:     sigprocmask(SIG_BLOCK, $sigset)
                    545:         or die "Can't block SIGINT for fork: $!\n";
                    546:     
                    547:     die "fork: $!" unless defined ($pid = fork);
                    548:     
                    549:     if ($pid) {
                    550:         # Parent records the child's birth and returns.
                    551:         sigprocmask(SIG_UNBLOCK, $sigset)
                    552:             or die "Can't unblock SIGINT for fork: $!\n";
                    553:         $children{$pid} = 1;
                    554:         $children++;
                    555:         return;
                    556:     } else {
                    557:         # Child can *not* return from this subroutine.
                    558:         $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
                    559:     
                    560:         # unblock signals
                    561:         sigprocmask(SIG_UNBLOCK, $sigset)
                    562:             or die "Can't unblock SIGINT for fork: $!\n";
                    563: 	
                    564: 	
                    565:         #open database handle
                    566: 	# making dbh global to avoid garbage collector
                    567: 	unless (
                    568: 		$dbh = DBI->connect("DBI:mysql:loncapa","www","SOMEPASSWORD",{ RaiseError =>0,PrintError=>0})
                    569: 		) { 
                    570: 	            my $st=120+int(rand(240));
                    571: 		    &logthis("<font color=blue>WARNING: Couldn't connect to database  ($st secs): $@</font>");
                    572: 		    print "database handle error\n";
                    573: 		    sleep($st);
                    574: 		    exit;
                    575: 
                    576: 	  };
                    577: 	# make sure that a database disconnection occurs with ending kill signals
                    578: 	$SIG{TERM}=$SIG{INT}=$SIG{QUIT}=$SIG{__DIE__}=\&DISCONNECT;
                    579: 
                    580:         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
                    581:         for ($i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
                    582:             $client = $server->accept()     or last;
                    583:             
                    584:             # do something with the connection
                    585: 	    $run = $run+1;
                    586: 	    my $userinput = <$client>;
                    587: 	    chomp($userinput);
                    588: 	    	    
                    589: 	    my ($conserver,$querytmp)=split(/&/,$userinput);
                    590: 	    my $query=unescape($querytmp);
                    591: 
                    592:             #send query id which is pid_unixdatetime_runningcounter
                    593: 	    $queryid = $thisserver;
                    594: 	    $queryid .="_".($$)."_";
                    595: 	    $queryid .= time."_";
                    596: 	    $queryid .= $run;
                    597: 	    print $client "$queryid\n";
                    598: 	    
                    599:             #prepare and execute the query
                    600: 	    my $sth = $dbh->prepare($query);
                    601: 	    my $result;
                    602: 	    unless ($sth->execute())
                    603: 	    {
                    604: 		&logthis("<font color=blue>WARNING: Could not retrieve from database: $@</font>");
                    605: 		$result="";
                    606: 	    }
                    607: 	    else {
                    608: 		my $r1=$sth->fetchall_arrayref;
                    609: 		my @r2; map {my $a=$_; my @b=map {escape($_)} @$a; push @r2,join(",", @b)} (@$r1);
                    610: 		$result=join("&",@r2) . "\n";
                    611: 	    }
                    612:             &reply("queryreply:$queryid:$result",$conserver);
                    613: 
                    614:         }
                    615:     
                    616:         # tidy up gracefully and finish
                    617: 	
                    618:         #close the database handle
                    619: 	$dbh->disconnect
                    620: 	   or &logthis("<font color=blue>WARNING: Couldn't disconnect from database  $DBI::errstr ($st secs): $@</font>");
                    621:     
                    622:         # this exit is VERY important, otherwise the child will become
                    623:         # a producer of more and more children, forking yourself into
                    624:         # process death.
                    625:         exit;
                    626:     }
                    627: }
1.5       harris41  628: </P>
                    629: <P>
                    630: <STRONG>** LOND enabling of MySQL requests</STRONG>
                    631: <BR />
                    632: This code is part of every lond child process in the
                    633: way that it parses command request syntax sent to it
                    634: from lonc processes.  Based on the diagram above, querysend
                    635: corresponds to B-lonc sending the result of the query.
                    636: queryreply corresponds to B-lond indicating that it has
                    637: received the request and will start the database transaction
                    638: (it returns "ok" to
                    639: A-lonc ($client)).
                    640: <PRE>
1.2       harris41  641: # ------------------------------------------------------------------- querysend
                    642:                    } elsif ($userinput =~ /^querysend/) {
                    643:                        my ($cmd,$query)=split(/:/,$userinput);
                    644: 		       $query=~s/\n*$//g;
                    645:                      print $client sqlreply("$hostid{$clientip}\&$query")."\n";
                    646: # ------------------------------------------------------------------ queryreply
                    647:                    } elsif ($userinput =~ /^queryreply/) {
                    648:                        my ($cmd,$id,$reply)=split(/:/,$userinput); 
                    649: 		       my $store;
                    650:                        my $execdir=$perlvar{'lonDaemons'};
                    651:                        if ($store=IO::File->new(">$execdir/tmp/$id")) {
                    652: 			   print $store $reply;
                    653: 			   close $store;
                    654: 			   print $client "ok\n";
                    655: 		       }
                    656: 		       else {
                    657: 			   print $client "error:$!\n";
                    658: 		       }
                    659: 
1.5       harris41  660: </PRE>
1.2       harris41  661: 
1.1       harris41  662: </P>
                    663: </BODY>
1.3       harris41  664: </HTML>

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>