SlideShare una empresa de Scribd logo
1 de 16
Descargar para leer sin conexión
Using Perl Stored
Procedures
with MariaDB
Antony T Curtis <atcurtis@gmail.com>
Special thanks to LinkedIn for permitting personal projects
Why Perl?
• CPAN
• "Multiplicity" / Thread-friendly.
• Lots of Perl code already written.
• MySQL UDFs have no access control.
• MySQL UDFs cannot execute dynamic SQL.
• Faster than “native” Stored Procedures.
Perl Stored Procedures
• Implemented as Perl modules.
• Use DBD::mysql to access database.
• Runs in-process with MariaDB.
• Easier to debug than SQL stored routines.
Hello World
MariaDB [Demo]> CREATE PROCEDURE PerlHello()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "HelloWorld::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [Demo]> call PerlHello();
+-----------------------+
| message |
+-----------------------+
| Hello World from Perl |
+-----------------------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
package HelloWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test()
{
return {
'message' => 'Hello World from Perl',
};
}
1;
Hello World
MariaDB [Demo]> CREATE PROCEDURE PerlHello()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "HelloWorld::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [Demo]> call PerlHello();
+-----------------------+
| message |
+-----------------------+
| Hello World from Perl |
+-----------------------+
1 row in set (0.03 sec)
Query OK, 0 rows affected (0.03 sec)
package HelloWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test()
{
return {
'message' => 'Hello World from Perl',
};
}
1;
Error handling or die
MariaDB [Demo]> CREATE PROCEDURE PerlError()
-> DYNAMIC RESULT SETS 1
-> NO SQL
-> LANGUAGE Perl
-> EXTERNAL NAME "GoodbyeWorld::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [Demo]> call PerlError();
ERROR 1220 (HY000): Cannot open file: No
such file or directory at /usr/local/mysql/
lib/plugin/perl/GoodbyeWorld.pm line 16.
package GoodbyeWorld;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
sub test(
{
open FILE, "</something/nonexist"
or die "Cannot open file: $!";
return {
'message' => 'Goodbye World from Perl',
};
}
1;
Reading Data
MariaDB [employees]> CREATE PROCEDURE employee(
-> empno INT)
-> DYNAMIC RESULT SETS 1
-> READS SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ReadData::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [employees]> call employee(10034)G
*************************** 1. row
***************************
birth_date: 1962-12-29
emp_no: 10034
first_name: Bader
gender: M
hire_date: 1988-09-21
last_name: Swan
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
package ReadData;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
our $DSN = ‘dbi:mysql:employees’;
use DBI;
use DBD::mysql;
sub test($)
{
my($emp_no) = @_;
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
my $s = $dbh->prepare(
“SELECT * FROM employees WHERE emp_no=?”);
$s->execute(int $emp_no);
return $s->fetchrow_hashref;
}
1;
Reading Data
MariaDB [employees]> CREATE PROCEDURE employee(
-> empno INT)
-> DYNAMIC RESULT SETS 1
-> READS SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ReadData::test";
Query OK, 0 rows affected (0.02 sec)
MariaDB [employees]> call employee(10034)G
*************************** 1. row
***************************
birth_date: 1962-12-29
emp_no: 10034
first_name: Bader
gender: M
hire_date: 1988-09-21
last_name: Swan
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
package ReadData;
# put this file in <prefix>/lib/mysql/perl
use 5.008008;
use strict;
use warnings;
use Symbol qw(delete_package);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( );
our @EXPORT = qw( test );
our $VERSION = '0.01';
our $DSN = ‘dbi:mysql:employees’;
use DBI;
use DBD::mysql;
sub test($)
{
my($emp_no) = @_;
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
my $s = $dbh->prepare(
“SELECT * FROM employees WHERE emp_no=?”);
$s->execute(int $emp_no);
return $s->fetchrow_hashref;
}
1;
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
MariaDB [employees]> select count(*)
-> from summary;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.15 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
Modifying Data
MariaDB [employees]> CREATE PROCEDURE
-> makesummary(
-> empno INT)
-> MODIFIES SQL DATA
-> LANGUAGE Perl
-> EXTERNAL NAME "ModifyData::test";
Query OK, 0 rows affected (0.00 sec)
MariaDB [employees]> call makesummary;
Query OK, 0 rows affected (18.02 sec)
MariaDB [employees]> select count(*)
-> from summary;
+----------+
| count(*) |
+----------+
| 300024 |
+----------+
1 row in set (0.15 sec)
sub test()
{
my $dbh = DBI->connect($DSN, undef, undef) ||
die "Failed in call to DBI->connect, $!";
$dbh->begin_work or die $!;
my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)");
my $emps = $dbh->selectall_arrayref(
"select emp_no, max(salary) salary from employees ".
"left join salaries using (emp_no) group by emp_no",
{ Slice => {} });
foreach my $emp (@$emps)
{
$ins->execute($emp->{emp_no}, $emp->{salary}) or die $!;
}
$dbh->commit or die $!;
return undef;
}
select statement - 2 seconds
300k inserts in 16 seconds
== 18k inserts per second
More than just procs
• CPAN is a large library...
• Can extend MariaDB’s functionality.
• How about using HTTP::Daemon?
Server Monitoring
sub daemon()
{
my $d = HTTP::Daemon->new(
LocalAddr => '127.0.0.1',
LocalPort => 8080,
) ||
die "Failed in call to HTTP::Daemon->new, $!";
my $dbh = DBI->connect("dbi:mysql:mysql", undef, undef) ||
die "Failed in call to DBI->connect, $!";
while (my $c = $d->accept)
{
while (my $r = $c->get_request)
{
if (exists $pages{$r->url->path})
{
$pages{$r->url->path}->($dbh, $c, $r);
}
else
{
$c->send_error(RC_NOT_FOUND);
}
}
$c->close;
undef $c;
}
}
What if we can use
HTTP::Daemon?
Server Monitoring
'/statusz' => sub {
my ($dbh,$c,$r) = @_;
return $c->send_error(RC_FORBIDDEN)
if $r->method ne 'GET';
my $sth = $dbh->prepare_cached(q{
SELECT VARIABLE_NAME name, VARIABLE_VALUE value
FROM INFORMATION_SCHEMA.GLOBAL_STATUS
}, { Slice => {} });
$sth->execute() || die $sth->errstr;
my $response = HTTP::Response->new(200, undef,
HTTP::Headers->new(
Content_Type => "application/json",
));
my $result = {};
while (my $row = $sth->fetchrow_arrayref)
{
$result->{$row->[0]} = $row->[1];
}
$response->add_content(to_json($result,
{ ascii => 1, pretty => 1 }));
return $c->send_response($response);
},
Fetching current
server status could be
as simple as fetching
http://127.0.0.1/statusz
Status
• Code hosted at LaunchPad.
• Contributing to MariaDB 10.0 soon.
• Stuff needs to be tidied up.
• Future steps include better Table Functions.

Más contenido relacionado

La actualidad más candente

New features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionNew features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionSveta Smirnova
 
MySQL Performance Schema in Action
MySQL Performance Schema in ActionMySQL Performance Schema in Action
MySQL Performance Schema in ActionSveta Smirnova
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadmCloud
 
DBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowDBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowAlex Zaballa
 
MySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossukMySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossukValeriy Kravchuk
 
Mysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50minsMysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50minsValeriy Kravchuk
 
MariaDB for developers
MariaDB for developersMariaDB for developers
MariaDB for developersColin Charles
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviewsJustin Swanhart
 
Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database JonesJohn David Duncan
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomValeriy Kravchuk
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL PerformanceSveta Smirnova
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbaiaadi Surve
 
Introduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sIntroduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sSveta Smirnova
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLJohn David Duncan
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingSveta Smirnova
 
Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013Valeriy Kravchuk
 
Why Use EXPLAIN FORMAT=JSON?
 Why Use EXPLAIN FORMAT=JSON?  Why Use EXPLAIN FORMAT=JSON?
Why Use EXPLAIN FORMAT=JSON? Sveta Smirnova
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingSveta Smirnova
 
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014Alex Zaballa
 
MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017Dave Stokes
 

La actualidad más candente (20)

New features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in actionNew features in Performance Schema 5.7 in action
New features in Performance Schema 5.7 in action
 
MySQL Performance Schema in Action
MySQL Performance Schema in ActionMySQL Performance Schema in Action
MySQL Performance Schema in Action
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
 
DBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should KnowDBA Commands and Concepts That Every Developer Should Know
DBA Commands and Concepts That Every Developer Should Know
 
MySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossukMySQL Performance schema missing_manual_flossuk
MySQL Performance schema missing_manual_flossuk
 
Mysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50minsMysql 56-experiences-bugs-solutions-50mins
Mysql 56-experiences-bugs-solutions-50mins
 
MariaDB for developers
MariaDB for developersMariaDB for developers
MariaDB for developers
 
Summary tables with flexviews
Summary tables with flexviewsSummary tables with flexviews
Summary tables with flexviews
 
Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
 
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL DevroomFlame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
Flame Graphs for MySQL DBAs - FOSDEM 2022 MySQL Devroom
 
Troubleshooting MySQL Performance
Troubleshooting MySQL PerformanceTroubleshooting MySQL Performance
Troubleshooting MySQL Performance
 
Php classes in mumbai
Php classes in mumbaiPhp classes in mumbai
Php classes in mumbai
 
Introduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]sIntroduction to MySQL Query Tuning for Dev[Op]s
Introduction to MySQL Query Tuning for Dev[Op]s
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
 
Performance Schema for MySQL Troubleshooting
Performance Schema for MySQL TroubleshootingPerformance Schema for MySQL Troubleshooting
Performance Schema for MySQL Troubleshooting
 
Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013Performance schema in_my_sql_5.6_pluk2013
Performance schema in_my_sql_5.6_pluk2013
 
Why Use EXPLAIN FORMAT=JSON?
 Why Use EXPLAIN FORMAT=JSON?  Why Use EXPLAIN FORMAT=JSON?
Why Use EXPLAIN FORMAT=JSON?
 
Performance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshootingPerformance Schema for MySQL troubleshooting
Performance Schema for MySQL troubleshooting
 
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
Flex Cluster e Flex ASM - GUOB Tech Day - OTN TOUR LA Brazil 2014
 
MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017MySQL 101 PHPTek 2017
MySQL 101 PHPTek 2017
 

Similar a Using Perl Stored Procedures for MariaDB

DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7chuvainc
 
DBD::SQLite
DBD::SQLiteDBD::SQLite
DBD::SQLitecharsbar
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenNETWAYS
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuRedis Labs
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks Damien Seguy
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Philip Zhong
 
The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196Mahmoud Samir Fayed
 
Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsNovelys
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDMydbops
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)Seungmin Yu
 
Service discovery and configuration provisioning
Service discovery and configuration provisioningService discovery and configuration provisioning
Service discovery and configuration provisioningSource Ministry
 

Similar a Using Perl Stored Procedures for MariaDB (20)

DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7DrupalCamp Foz - Novas APIs Drupal 7
DrupalCamp Foz - Novas APIs Drupal 7
 
MySQLinsanity
MySQLinsanityMySQLinsanity
MySQLinsanity
 
DBD::SQLite
DBD::SQLiteDBD::SQLite
DBD::SQLite
 
Triggers and Stored Procedures
Triggers and Stored ProceduresTriggers and Stored Procedures
Triggers and Stored Procedures
 
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert VanderkelenOSMC 2008 | Monitoring MySQL by Geert Vanderkelen
OSMC 2008 | Monitoring MySQL by Geert Vanderkelen
 
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, HerokuPostgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
Postgres & Redis Sitting in a Tree- Rimas Silkaitis, Heroku
 
PHP tips and tricks
PHP tips and tricks PHP tips and tricks
PHP tips and tricks
 
Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8Compare mysql5.1.50 mysql5.5.8
Compare mysql5.1.50 mysql5.5.8
 
Instalar MySQL CentOS
Instalar MySQL CentOSInstalar MySQL CentOS
Instalar MySQL CentOS
 
My sql1
My sql1My sql1
My sql1
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
veracruz
veracruzveracruz
veracruz
 
php2.pptx
php2.pptxphp2.pptx
php2.pptx
 
The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196The Ring programming language version 1.7 book - Part 31 of 196
The Ring programming language version 1.7 book - Part 31 of 196
 
Presentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-railsPresentation technico-commercial-ruby-on-rails
Presentation technico-commercial-ruby-on-rails
 
Replication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTIDReplication Troubleshooting in Classic VS GTID
Replication Troubleshooting in Classic VS GTID
 
MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)MySQL InnoDB Cluster 미리보기 (remote cluster test)
MySQL InnoDB Cluster 미리보기 (remote cluster test)
 
Service discovery and configuration provisioning
Service discovery and configuration provisioningService discovery and configuration provisioning
Service discovery and configuration provisioning
 

Último

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...apidays
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessPixlogix Infotech
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfhans926745
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 

Último (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 

Using Perl Stored Procedures for MariaDB

  • 1. Using Perl Stored Procedures with MariaDB Antony T Curtis <atcurtis@gmail.com> Special thanks to LinkedIn for permitting personal projects
  • 2. Why Perl? • CPAN • "Multiplicity" / Thread-friendly. • Lots of Perl code already written. • MySQL UDFs have no access control. • MySQL UDFs cannot execute dynamic SQL. • Faster than “native” Stored Procedures.
  • 3. Perl Stored Procedures • Implemented as Perl modules. • Use DBD::mysql to access database. • Runs in-process with MariaDB. • Easier to debug than SQL stored routines.
  • 4. Hello World MariaDB [Demo]> CREATE PROCEDURE PerlHello() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "HelloWorld::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [Demo]> call PerlHello(); +-----------------------+ | message | +-----------------------+ | Hello World from Perl | +-----------------------+ 1 row in set (0.03 sec) Query OK, 0 rows affected (0.03 sec) package HelloWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test() { return { 'message' => 'Hello World from Perl', }; } 1;
  • 5. Hello World MariaDB [Demo]> CREATE PROCEDURE PerlHello() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "HelloWorld::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [Demo]> call PerlHello(); +-----------------------+ | message | +-----------------------+ | Hello World from Perl | +-----------------------+ 1 row in set (0.03 sec) Query OK, 0 rows affected (0.03 sec) package HelloWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test() { return { 'message' => 'Hello World from Perl', }; } 1;
  • 6. Error handling or die MariaDB [Demo]> CREATE PROCEDURE PerlError() -> DYNAMIC RESULT SETS 1 -> NO SQL -> LANGUAGE Perl -> EXTERNAL NAME "GoodbyeWorld::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [Demo]> call PerlError(); ERROR 1220 (HY000): Cannot open file: No such file or directory at /usr/local/mysql/ lib/plugin/perl/GoodbyeWorld.pm line 16. package GoodbyeWorld; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; sub test( { open FILE, "</something/nonexist" or die "Cannot open file: $!"; return { 'message' => 'Goodbye World from Perl', }; } 1;
  • 7. Reading Data MariaDB [employees]> CREATE PROCEDURE employee( -> empno INT) -> DYNAMIC RESULT SETS 1 -> READS SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ReadData::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [employees]> call employee(10034)G *************************** 1. row *************************** birth_date: 1962-12-29 emp_no: 10034 first_name: Bader gender: M hire_date: 1988-09-21 last_name: Swan 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) package ReadData; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; our $DSN = ‘dbi:mysql:employees’; use DBI; use DBD::mysql; sub test($) { my($emp_no) = @_; my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; my $s = $dbh->prepare( “SELECT * FROM employees WHERE emp_no=?”); $s->execute(int $emp_no); return $s->fetchrow_hashref; } 1;
  • 8. Reading Data MariaDB [employees]> CREATE PROCEDURE employee( -> empno INT) -> DYNAMIC RESULT SETS 1 -> READS SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ReadData::test"; Query OK, 0 rows affected (0.02 sec) MariaDB [employees]> call employee(10034)G *************************** 1. row *************************** birth_date: 1962-12-29 emp_no: 10034 first_name: Bader gender: M hire_date: 1988-09-21 last_name: Swan 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) package ReadData; # put this file in <prefix>/lib/mysql/perl use 5.008008; use strict; use warnings; use Symbol qw(delete_package); require Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( ); our @EXPORT = qw( test ); our $VERSION = '0.01'; our $DSN = ‘dbi:mysql:employees’; use DBI; use DBD::mysql; sub test($) { my($emp_no) = @_; my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; my $s = $dbh->prepare( “SELECT * FROM employees WHERE emp_no=?”); $s->execute(int $emp_no); return $s->fetchrow_hashref; } 1;
  • 9. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 10. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 11. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) MariaDB [employees]> select count(*) -> from summary; +----------+ | count(*) | +----------+ | 300024 | +----------+ 1 row in set (0.15 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; }
  • 12. Modifying Data MariaDB [employees]> CREATE PROCEDURE -> makesummary( -> empno INT) -> MODIFIES SQL DATA -> LANGUAGE Perl -> EXTERNAL NAME "ModifyData::test"; Query OK, 0 rows affected (0.00 sec) MariaDB [employees]> call makesummary; Query OK, 0 rows affected (18.02 sec) MariaDB [employees]> select count(*) -> from summary; +----------+ | count(*) | +----------+ | 300024 | +----------+ 1 row in set (0.15 sec) sub test() { my $dbh = DBI->connect($DSN, undef, undef) || die "Failed in call to DBI->connect, $!"; $dbh->begin_work or die $!; my $ins = $dbh->prepare("INSERT INTO summary VALUES (?,?)"); my $emps = $dbh->selectall_arrayref( "select emp_no, max(salary) salary from employees ". "left join salaries using (emp_no) group by emp_no", { Slice => {} }); foreach my $emp (@$emps) { $ins->execute($emp->{emp_no}, $emp->{salary}) or die $!; } $dbh->commit or die $!; return undef; } select statement - 2 seconds 300k inserts in 16 seconds == 18k inserts per second
  • 13. More than just procs • CPAN is a large library... • Can extend MariaDB’s functionality. • How about using HTTP::Daemon?
  • 14. Server Monitoring sub daemon() { my $d = HTTP::Daemon->new( LocalAddr => '127.0.0.1', LocalPort => 8080, ) || die "Failed in call to HTTP::Daemon->new, $!"; my $dbh = DBI->connect("dbi:mysql:mysql", undef, undef) || die "Failed in call to DBI->connect, $!"; while (my $c = $d->accept) { while (my $r = $c->get_request) { if (exists $pages{$r->url->path}) { $pages{$r->url->path}->($dbh, $c, $r); } else { $c->send_error(RC_NOT_FOUND); } } $c->close; undef $c; } } What if we can use HTTP::Daemon?
  • 15. Server Monitoring '/statusz' => sub { my ($dbh,$c,$r) = @_; return $c->send_error(RC_FORBIDDEN) if $r->method ne 'GET'; my $sth = $dbh->prepare_cached(q{ SELECT VARIABLE_NAME name, VARIABLE_VALUE value FROM INFORMATION_SCHEMA.GLOBAL_STATUS }, { Slice => {} }); $sth->execute() || die $sth->errstr; my $response = HTTP::Response->new(200, undef, HTTP::Headers->new( Content_Type => "application/json", )); my $result = {}; while (my $row = $sth->fetchrow_arrayref) { $result->{$row->[0]} = $row->[1]; } $response->add_content(to_json($result, { ascii => 1, pretty => 1 })); return $c->send_response($response); }, Fetching current server status could be as simple as fetching http://127.0.0.1/statusz
  • 16. Status • Code hosted at LaunchPad. • Contributing to MariaDB 10.0 soon. • Stuff needs to be tidied up. • Future steps include better Table Functions.