Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot load file mysql2 on AWS Lambda

Trying to have a Lambda connect to an RDS database but can't get the mysql2 gem to load. Tried the pristine instruction but that didn't resolve the issue.

I've got the built mysql2 gem in the vendor directory. Did this using bundle install --deployment.

Presumably this is a problem because of the compiled extensions used by mysql2. Not sure how I can sort this for AWS Lambda though. Thoughts?

Here's the log output:

START RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b Version: $LATEST
Ignoring mysql2-0.5.2 because its extensions are not built. Try: gem pristine mysql2 --version 0.5.2
Init error when loading handler lambda_function.lambda_handler
{
  "errorMessage": "cannot load such file -- mysql2",
  "errorType": "Init<LoadError>",
  "stackTrace": [
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/task/lambda_function.rb:3:in `<top (required)>'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'",
    "/var/lang/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'"
  ]
}
END RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b
REPORT RequestId: 62f35c49-039f-11e9-be04-1fd1111df42b  Duration: 1439.17 ms    Billed Duration: 1500 ms    Memory Size: 128 MB Max Memory Used: 17 MB  
Unknown application error occurred
Init<LoadError>

Here's my Gemfile:

source 'https://rubygems.org'

gem 'mysql2', '~> 0.5.2'
gem 'sequel', '~> 5.15.0'

Gemfile.lock

GEM
remote: https://rubygems.org/
specs:
  mysql2 (0.5.2)
  sequel (5.15.0)

PLATFORMS
  ruby

DEPENDENCIES
  mysql2 (~> 0.5.2)
  sequel (~> 5.15.0)

BUNDLED WITH
  1.17.2

Here's the top of my lambda_function.rb file

require 'json'
require 'logger'
require 'mysql2'
require 'sequel'
like image 286
James Avatar asked Sep 05 '25 07:09

James


1 Answers

Dhanabal's answer works but lets me elaborate more since the answer is too procedural for me.

Basically, a gem with native extension should build on the same environment as AWS Lambda.
So we need to build native extension inside lambci/lambda:build-ruby2.5 docker image that mimics Lambda environment.

Also, we need to copy dynamic libraries into the load path.
First, let's find out where can we place the libraries.
echo $LD_LIBRARY_PATH in the container and you'll get /var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib.
So, I simply copy the library from /usr/lib64/mysql to [function dir]/lib and deploy.

That's it.

like image 124
Curious Sam Avatar answered Sep 07 '25 20:09

Curious Sam